Introduction and research question

Life-Expectancy has constantly increased over the last centuries, and it has never been so high as nowadays. Medicine has taken great strides forward, eradicating and finding cures for a lot of mortal diseases. Having said that, there are still other big challenges that we have to face in medicine and one of those is for sure cancer. Cancer is a leading cause of death all over the world, accounting for almost 10 million deaths in 2020.

This is the reason why we thought that would be very interesting to analyze the principal factors that, according to state-of-the-art scientific research, cause this disease. We also wanted to divide these factors into some macro-groups of variables: environmental, lifestyle-related, and socio-economical/demographic.

Our analysis (purely statistical) aims to verify if it is indeed possible to use data about the selected risk factors to predict the share of people with cancer in a given year and a given country. Moreover, we tried to improve our all-inclusive model by finding the best model out of the above-mentioned factors.

Dataset, Data Cleaning and Data Visualization

Source

Our research started by searching out on some reliable websites what are the leading causes of cancer and dividing them into the macro-categories. To do that we adopted the WHO official website and we selected the following risk factors:

  • ENVIRONMENTAL: Air pollution
  • LIFE-STYLE RELATED: Alcohol consumption, Tobacco consumption, Obesity
  • SOCIO-ECONOMICAL/DEMOGRAPHIC: GDP, Share of old people

(IMPORTANT DISCLAMER: of course the factors defined under “Socio-Economical/Demographic” cannot be considered to cause cancer, but as we will see they turn out to be very useful to model cancer all over the world and over time)

Description of the variables

We built our dataset selecting by merging different csv files all taken from the same source, that is called “Our world in data”. This is by itself collecting datasets from verified sources and the precise reference to each factor is given in the sitography at the end of the paper. Here we provide a complete description of the variable we decided to use in our model.

Cancer: Share of total population with any form of cancer, measured as the age-standardized percentage. This share has been age-standardized assuming a constant age structure to compare prevalence between countries and through time.

Air_pollution: Population-weighted average level of exposure to concentrations of suspended particles measuring less than 2.5 microns in diameter (PM2.5). Exposure is measured in micro grams of PM2.5 per cubic meter (µg/m³).

Alcohol: Average per capta consumption of alcoholic beverages, measured in kilograms per year. Data is based on per capta food supply at the consumer level, but does not account for food waste at the consumer level

GDP per capta: Measured in constant international-$

Obesity: Obesity is defined as having a body-mass index (BMI) equal to or greater than 30. BMI is a person’s weight in kilograms divided by his or her height in metres squared

Old age Dependency: This is the ratio of the number of people older than 64 relative to the number of people in the working-age (15-64 years). Data are shown as the proportion of dependents per 100 working-age population.

Smoking: Share of population who smoke every day

Constructing the table

We started by loading all the different csv files. Then we took the column we were interested in and we glued them together. After some other little manipulation here is how part of the final table looks like (the complete table with the N.A.s results in a dimension of 6468x11):

##We start by loading some useful libraries that we will need during this process

library(readr) #Used to read the csv
library(tidyverse) #Contains a lot of useful packages to clean the datas
library(gganimate) #To create animated plots
library(ggthemes) #To select some nice themes 
library(zoo) #To fill the N.A. values 
library(grid) #To display plots into a grid
library(gridExtra) #To display plots into a grid
library(ggpubr)#To display plots into a grid

##We now load the row csv files what we need to merge 

Cancer <- read_csv("Datasets/Cancer.csv")
Air_pollution <- read_csv("Datasets/Air pollution.csv")
Alcool <- read_csv("Datasets/Alcool.csv")
GDP_per_capta <- read_csv("Datasets/GDP per capta.csv")
Obesity <- read_csv("Datasets/Obesity.csv")
Old_age_dependency_ratio <- read_csv("Datasets/Old age dependency ratio.csv")
Smoking <- read_csv("Datasets/Smoking.csv")
Population <- read_csv("Datasets/population-since-1800.csv")
countryContinent <- read_csv("Datasets/countryContinent.csv")

#We proceed by taking the explanatory variable data set (Cancer) and adding the covariates as columns other columns, to do that we use the use the libraby "dplyr" as it makes it very easy to do and readable

Continent = countryContinent %>% select(country, continent)
Continentt = rename(Continent, Entity = country)
Cancer1 = left_join(Cancer, Air_pollution, by = c("Entity", "Code", "Year"))
Cancer2 = left_join(Cancer1, Alcool, by = c("Entity", "Code", "Year"))
Cancer3 = left_join(Cancer2, GDP_per_capta, by = c("Entity", "Code", "Year"))
Cancer4 = left_join(Cancer3, Obesity, by = c("Entity", "Code", "Year"))
Cancer5 = left_join(Cancer4, Old_age_dependency_ratio, by = c("Entity", "Code", "Year"))
Cancer6 = left_join(Cancer5, Smoking, by = c("Entity", "Code", "Year"))
Cancer7 = left_join(Cancer6, Continentt, by = "Entity")
Cancer_final = Cancer7

rm("Cancer1", "Cancer2", "Cancer3", "Cancer4", "Cancer5", "Cancer6", "Cancer7")
rm("Air_pollution", "Alcool", "Cancer", "GDP_per_capta", "Obesity", "Old_age_dependency_ratio", "Smoking", "Continent", "Continentt", "countryContinent")

#We now proceed by renaming the columns. This will make all the manipulations of the dataframe more readable:

colnames(Cancer_final)[4] <- "Cancer"
colnames(Cancer_final)[5] <- "AirPoll"
colnames(Cancer_final)[6] <- "Alcool"
colnames(Cancer_final)[7] <- "GDP"
colnames(Cancer_final)[8] <- "Obesity"
colnames(Cancer_final)[9] <- "Age"
colnames(Cancer_final)[10] <- "Smoking"

Cancer_final
write.csv(Cancer_final, "Cancer_final.csv", row.names=FALSE, quote=FALSE) #to save the file into our environment

Data Visualization

Now we will proceed with some plotting. Again, for the detailed process for making this graphs please refer to the R script. You may also want to check our our file in Html format, in which we made some nice animation to be able to display the evolution in time of the variables.

We start by displaying the variable we are interested to explain, that is the share of population with any form of cancer. We chose to plot the most recent year in our data frame, that is 2017. As we can clearly see form the plot below the countries in which are suffering more (in percentage) of cancer are USA, Canada, Australia and Greenland. These states are followed by European countries. Asian and African countries are the ones with relatively less cases of cancer in percentage. Here we could argue that a big downside of this picture is the fact that different countries have different ability in the process of screening. As the WHO writes “Late-stage presentation and lack of access to diagnosis and treatment are common, particularly in low- and middle-income countries” and we will further discuss this limitation in the dedicated section.

(Countries for which data were not available are omitted from the map, but those are luckily few)

#We read the file needed
share_of_population_with_cancer <- read_csv("Cancer.csv")  #read the file 
share_of_population_with_cancer = data.frame(lapply(share_of_population_with_cancer, function(x) {
  gsub("United States", "USA", x) #correction needed for the mapping 
}))
colnames(share_of_population_with_cancer)[1] <- "region" #Give the same name for the country in the two datasets
colnames(share_of_population_with_cancer)[4] <- "cancer" #Dropping the complicated name given by the data frame

# Create the actual map that we will use
#We will use the ggplo2 package for that

mapdata = map_data("world") #Used to take the latitude and longitude of the countries 
mapp <- mapdata %>%
  left_join(share_of_population_with_cancer, by = "region") #merge the two datasets
mapp2 = mapp %>% 
  filter(!is.na(mapp$cancer)) #dealing with NA
mapp2$cancer <- as.numeric(mapp2$cancer) #changing the value to numeric for plotting
mapp2$Year <- as.numeric(mapp2$Year) #changing the value to numeric for animation
# Building the map
#Here we create a static map
ggplot( data = mapp2, aes(long, lat, group = subregion)) +
  geom_map(
    aes(map_id = region),
    map = mapdata,
    color = "black", fill = "gray30", size = 0.3
  ) +
  geom_polygon(aes(group = group, fill = cancer), color = "black") +
  scale_fill_gradient2(low = "blue", high = "red" , midpoint = 1.0355583) +
  theme_minimal() +
  transition_time(Year)
  labs(
    title = "Share of population with cancer in {round(frame_time}",
    x = "", y = "", fill = ""
    ) +
  theme_bw()
  shadow_wake(wake_length = 0.05)
animate(graphPoll, height = 500, width = 800, fps = 30, duration = 15, end_pause = 60, res = 100)
anim_save("Share with cancer world.gif")

-> This is not the file you would get running the code, but its static version, My computer just doesn’t have enough computational power to produce this animation and shuts down when I try to create the animation : ( if you want to buy me a new MacBook Pro 16’’ with the M1 MAX chip feel free to contact me

Now we are going to explore the dataset by plotting each selected factor against the Cancer one to start having an idea of some possible relation. Because we selected them as “risk factors” we would expect to see some positive correlation going on. To be consistent with what we have done above we again plot the graphs relative to the year 2017. We also used some libraries to make plots nicer by coloring the points according to the continent and by changing the size according to the population of the country.

The result is the following:

#Here we correct the N.A.s by filling the closest non empty value (this is needed for plotting)
#and we will not do any analysis with these fake data
Cancergraph = left_join(Cancer_final, Population, by = c("Entity", "Code", "Year"))
Cancergraph$Smoking = na.locf(Cancergraph$Smoking)
Cancergraph$AirPoll = na.locf(Cancergraph$AirPoll)
Cancergraph$Alcool = na.locf(Cancergraph$Alcool)
Cancergraph$GDP = na.locf(Cancergraph$GDP, fromLast = TRUE)
Cancergraph$Age = na.locf(Cancergraph$Age)
Cancergraph$Obesity = na.locf(Cancergraph$Obesity)
Cancergraph$`Population (historical estimates)` = na.locf(Cancergraph$`Population (historical estimates)`)
#Here we create and save each plot, This chunk of code will not be evaluated every time because is pretty heavy and time/CPU consuming. The results (trust me) are included at the end
graphPoll = Cancergraph %>%
  ggplot(aes(x = AirPoll, y = Cancer, color = continent, size = `Population (historical estimates)`)) +
  geom_point(alpha = 0.9, stroke = 0) +
  scale_size(range = c(2,12), guide = "none") +
  scale_color_brewer(palette = "Set2") +
  labs(title = "Cancer incidence vs Air Pollution", 
       x = "Air pollution exposure ", 
       y = "Share of people with Cancer",
       color = "Continent",
       caption = "Source: Our World in Data") +
  transition_time(Year) +
  labs (subtitle = "Year:{round(frame_time)}") 
 shadow_wake(wake_length = 0.05)
animate(graphPoll, height = 500, width = 800, fps = 30, duration = 15, end_pause = 60, res = 100)
anim_save("Airpoll Visual Animation.gif")


graphAlco = Cancergraph %>%
  ggplot(aes(x = Alcool, y = Cancer, color = continent, size = `Population (historical estimates)`)) +
  geom_point(alpha = 0.9, stroke = 0) +
  scale_size(range = c(2,12), guide = "none") +
  scale_color_brewer(palette = "Set2") +
  labs(title = "Cancer incidence vs Alcool consumption", 
       x = "Alcool consumed", 
       y = "Share of people with Cancer",
       color = "Continent",
       caption = "Source: Our World in Data") +
  transition_time(Year) +
  labs (subtitle = "Year:{round(frame_time)}") 
 shadow_wake(wake_length = 0.05)
animate(graphAlco, height = 500, width = 800, fps = 30, duration = 15, end_pause = 60, res = 100)
anim_save("Alcool Visual Animation.gif")


graphGDP = Cancergraph %>%
  ggplot(aes(x = GDP, y = Cancer, color = continent, size = `Population (historical estimates)`)) +
  geom_point(alpha = 0.9, stroke = 0) +
  scale_size(range = c(2,12), guide = "none") +
  scale_color_brewer(palette = "Set2") +
  labs(title = "Cancer incidence vs GDP", 
       x = "GDP per capta", 
       y = "Share of people with Cancer",
       color = "Continent",
       caption = "Source: Our World in Data") +
  transition_time(Year) +
  labs (subtitle = "Year:{round(frame_time)}") 
 shadow_wake(wake_length = 0.05)
animate(graphGDP, height = 500, width = 800, fps = 30, duration = 15, end_pause = 60, res = 100)
anim_save("GDP Visual Animation.gif")


graphObes = Cancergraph %>%
  ggplot(aes(x = Obesity, y = Cancer, color = continent, size = `Population (historical estimates)`)) +
  geom_point(alpha = 0.9, stroke = 0) +
  scale_size(range = c(2,12), guide = "none") +
  scale_color_brewer(palette = "Set2") +
  labs(title = "Cancer incidence vs Obesity", 
       x = "Share of Obese people", 
       y = "Share of people with Cancer",
       color = "Continent",
       caption = "Source: Our World in Data") +
  transition_time(Year) +
  labs (subtitle = "Year:{round(frame_time)}") 
 shadow_wake(wake_length = 0.05)
animate(graphObes, height = 500, width = 800, fps = 30, duration = 15, end_pause = 60, res = 100)
anim_save("Obesity Visual Animation.gif")


graphAge = Cancergraph %>%
  ggplot(aes(x = Age, y = Cancer, color = continent, size = `Population (historical estimates)`)) +
  geom_point(alpha = 0.9, stroke = 0) +
  scale_size(range = c(2,12), guide = "none") +
  scale_color_brewer(palette = "Set2") +
  labs(title = "Cancer incidence vs Age", 
       x = "Old people ratio", 
       y = "Share of people with Cancer",
       color = "Continent",
       caption = "Source: Our World in Data") +
  transition_time(Year) +
  labs (subtitle = "Year:{round(frame_time)}") 
 shadow_wake(wake_length = 0.05)
animate(graphAge, height = 500, width = 800, fps = 30, duration = 15, end_pause = 60, res = 100)
anim_save("Age Visual Animation.gif")


graphSmoke = Cancergraph %>%
  ggplot(aes(x = Smoking, y = Cancer, color = continent, size = `Population (historical estimates)`)) +
  geom_point(alpha = 0.9, stroke = 0) +
  scale_size(range = c(2,12), guide = "none") +
  scale_color_brewer(palette = "Set2") +
  labs(title = "Cancer incidence vs Smoking", 
       x = "Number of Smokers", 
       y = "Share of people with Cancer",
       color = "Continent",
       caption = "Source: Our World in Data") +
  transition_time(Year) +
  labs (subtitle = "Year:{round(frame_time)}") 
 shadow_wake(wake_length = 0.05)
animate(graphSmoke, height = 500, width = 800, fps = 30, duration = 15, end_pause = 60, res = 100)
anim_save("Smoking Visual Animation 3.gif")
#And eventually here it is the animations:
knitr::include_graphics("Airpoll Visual Animation.gif")

knitr::include_graphics("Alcool Visual Animation.gif")

knitr::include_graphics("GDP Visual Animation.gif")

knitr::include_graphics("Obesity Visual Animation.gif")

knitr::include_graphics("Age Visual Animation.gif")

knitr::include_graphics("Smoking Visual Animation 3.gif")

Our hypothesis is confirmed by these graphs: evidently there’s some sort of positive correlation, but still not strong as we imagined beforehand. We can see that age is the factor which presents a stronger correlation visually.The only problem is the one related to Air pollution. Our explanation for that is that will be provided in the section “Limitations of the study”.

We also have some outliers, which are Canada and US (The two orange points that on each graph are above the others). Being cancer causes such a complicated and intricate thing, is actually quite difficult to really understand why those two countries have such an high number of cases. We can suppose that these two countries perform a more intense screening activity, but this goes beyond the scope of this study. We will just delete these two countries from our data set. Having said that, the result that follow will be not significantly changed by this action.

Multivariate Linear Regression

We are now going to perform a multivariate linear regression, trying to examine the relationship between some explanatory variables and one response variable. As mentioned before, we are going to take into consideration as explanatory variables all the factors selected to help us try to explain part of the variance of the share of people affected by cancer worldwide. The table used is considering approximately 150 countries for approximately 20 years. In this way, we will be able to do not miss some trend or to do not be deceived by some outliers years/countries or random trends.

Now, let’s proceed with performing the actual multiple linear regression. After that, we want to see if the assumptions required to state the statistical significance are met: we’ll check for the normality and the homoscedasticity of the residuals.

library(olsrr)

# Delete the N.A.s
mydata = read.csv("Cancer_final.csv")
data5 = na.omit(mydata)

# Delete USA and Canada from the data set
data3 = subset(data5, Entity != "USA")

#Normality of the residuals
model = lm( Cancer~ Smoking + Obesity + GDP + Age + AirPoll + Alcool, data = data3)

#Perform Testing for normality of residuals
ols_test_normality(model)
## -----------------------------------------------
##        Test             Statistic       pvalue  
## -----------------------------------------------
## Shapiro-Wilk              0.722          0.0000 
## Kolmogorov-Smirnov        0.1671         0.0000 
## Cramer-von Mises         216.6397        0.0000 
## Anderson-Darling         46.5541         0.0000 
## -----------------------------------------------
#plot histogram of residuals
kop = residuals.lm(model)
hist(kop, breaks = 50)

#Check graphically using the function plot
plot(model)

Let’s analyze each of the test we performed above and see which conclusion we can take from what we observed. For what concerns normality of the residuals, we can see that the p-value of the tests we performed is below the 0.05 significance level for all of them, thus we can reject the null hypothesis that the errors are normally distributed. This is exactly as we imagined: the data set is made by more or less 1000 data points, thus violating this assumption was something that we expected for. This is due to the fact that with this many data points it’s easy for the testing methods to find evidence against normality. Trying to see the situation graphically, the situations seems a bit better. The qq-plot shows that the data fit not that badly the diagonal line, exceptions made for a little deviation near the top-right. Furthermore, analyzing another graph we see that plotting the residuals against the fitted values approximates more or less a straight line. The analysis of the residuals is enough satisfying, but if we want to be strict we will say that we are not able to take out any significant conclusions from the experiment we will carry on.

We now perform and interpret the result of the multiple linear regression itself.

summary(model)
## 
## Call:
## lm(formula = Cancer ~ Smoking + Obesity + GDP + Age + AirPoll + 
##     Alcool, data = data3)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.71319 -0.14060 -0.02478  0.08123  2.64302 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.020e-01  4.013e-02   5.035 5.74e-07 ***
## Smoking     -2.872e-03  1.371e-03  -2.095 0.036418 *  
## Obesity      2.647e-03  1.414e-03   1.871 0.061588 .  
## GDP          1.666e-05  9.009e-07  18.497  < 2e-16 ***
## Age          5.045e-02  2.250e-03  22.419  < 2e-16 ***
## AirPoll     -4.296e-03  6.737e-04  -6.377 2.83e-10 ***
## Alcool       1.150e-03  3.259e-04   3.528 0.000439 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.3053 on 941 degrees of freedom
## Multiple R-squared:  0.8243, Adjusted R-squared:  0.8232 
## F-statistic:   736 on 6 and 941 DF,  p-value: < 2.2e-16

From just these results, we can see various things: the value of the Adjusted R-Squared is very satisfying, and then this model fits pretty well the data, telling us there is a quite good relationship with the covariates we indicated: our factors explain a 82% variance in the share of population with cancer! We are actually considering the Adjusted R-Squared since we are performing a multivariate linear regression, and thus the number of factors we include in our model is relevant and we want to penalize bigger models. In fact we know that the simply value of R-Squared can just increase when adding more factors, even if those are completely random ones. In addition, all the variables seem to explain pretty well the share of cancer cases:almost all of the p-values are statistically significant! The only exception is given by the “Obesity” explanatory variable.

Model Selection (Testing)

Now that we discussed the linear model and the underlying characteristics, we want to do some basic model selection to see if there are other models (possibly simpler) that are able to explain the dependent variable well enough. To do that we will leverage on two different approach to model selection. The first is the one provided by testing and the other the one provided by information theory. We will compare the results and see whether they coincide or not.

We start by importing the data we will need for the model selection and loading some useful libraries. We will then create our linear model using all the covariates and the dataset without the missing values (we will use the same model obtained above with the regression)

library(olsrr) #This stands for Ordinary Least SquaRe Regression and it has the tools needed
model = lm( Cancer ~ Smoking + Obesity + GDP + Age + AirPoll + Alcool, data = data3)
summary(model)
## 
## Call:
## lm(formula = Cancer ~ Smoking + Obesity + GDP + Age + AirPoll + 
##     Alcool, data = data3)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.71319 -0.14060 -0.02478  0.08123  2.64302 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.020e-01  4.013e-02   5.035 5.74e-07 ***
## Smoking     -2.872e-03  1.371e-03  -2.095 0.036418 *  
## Obesity      2.647e-03  1.414e-03   1.871 0.061588 .  
## GDP          1.666e-05  9.009e-07  18.497  < 2e-16 ***
## Age          5.045e-02  2.250e-03  22.419  < 2e-16 ***
## AirPoll     -4.296e-03  6.737e-04  -6.377 2.83e-10 ***
## Alcool       1.150e-03  3.259e-04   3.528 0.000439 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.3053 on 941 degrees of freedom
## Multiple R-squared:  0.8243, Adjusted R-squared:  0.8232 
## F-statistic:   736 on 6 and 941 DF,  p-value: < 2.2e-16

We begin by trying three different testing methods, called respectively “Step-up/Forward”, “Step-down/Backward” and “Step-both”. The fist two act in a dual way with respect to the second and the last is in a way able to overcome the downsides of the first two models. Without entering too much into the details this greedy methodology starts with no(all) predictors in the model and iteratively add(subtract) the one that is more statistically significant in contributing to the model. The procedure automatically stops when no other variables can be added to gain statistical significance. In practice what we do at each step is to perform a t-test for each candidate variable and see which one has the lowest p-value (if there is one). In this setting we kept a significance level of 0.05 both for entering and for exiting the model.

The Step-up method yields:

frwfit <- ols_step_forward_p(model, pent = 0.05)
frwfit
## 
##                             Selection Summary                              
## --------------------------------------------------------------------------
##         Variable                  Adj.                                        
## Step    Entered     R-Square    R-Square      C(p)        AIC        RMSE     
## --------------------------------------------------------------------------
##    1    Age           0.7156      0.7153    579.6198    896.8510    0.3875    
##    2    GDP           0.8108      0.8104     71.6307    512.4933    0.3162    
##    3    AirPoll       0.8210      0.8204     19.0720    462.0425    0.3078    
##    4    Alcool        0.8231      0.8224      9.5664    452.6010    0.3061    
## --------------------------------------------------------------------------

The selection led us to add to the model the “Age”, “GDP”, “Airpoll” and “Alcool”. We now try the symmetrical method,

The Step-down method yields:

bkwfit <- ols_step_backward_p(model, prem = 0.05)
bkwfit
## 
## 
##                           Elimination Summary                            
## ------------------------------------------------------------------------
##         Variable                  Adj.                                      
## Step    Removed     R-Square    R-Square     C(p)       AIC        RMSE     
## ------------------------------------------------------------------------
##    1    Obesity       0.8237      0.8227    8.5024    451.5307    0.3057    
##    2    Smoking       0.8231      0.8224    9.5664    452.6010    0.3061    
## ------------------------------------------------------------------------

As you can see we got the same result here: we rejected the “Obesity” and the “Smoking” cofactor. Notice that even if the methods seem completely specular, it’s not granted that they’ll lead us to the same outcome.

To do one last cross-check using testing methods we use a mixed method to allow variables that were added in previous steps to be excluded in succeeding steps (this wasn’t allowed in the simple forward/step-up method)

The “Step-both” method yields:

bothfit <- ols_step_both_p(model, pent = 0.05, prem = 0.05)
bothfit
## 
##                               Stepwise Selection Summary                               
## --------------------------------------------------------------------------------------
##                      Added/                   Adj.                                        
## Step    Variable    Removed     R-Square    R-Square      C(p)        AIC        RMSE     
## --------------------------------------------------------------------------------------
##    1      Age       addition       0.716       0.715    579.6200    896.8510    0.3875    
##    2      GDP       addition       0.811       0.810     71.6310    512.4933    0.3162    
##    3    AirPoll     addition       0.821       0.820     19.0720    462.0425    0.3078    
##    4     Alcool     addition       0.823       0.822      9.5660    452.6010    0.3061    
## --------------------------------------------------------------------------------------

But this again yields the same result as the one we got with the step forward method. As well as before, the fact that we obtained the same result with all the three approaches is a very likable. This seems to suggest a model of four variables that is cutting “Smoking” and “Obesity”, given that these two risk factor are removed by all three of our greedy methods.

We now try all together different methods based on Information criterion. These work in such a way that they penalize big models that otherwise would be selected by methods such as LSE and MLE. The math underneath this approach is absolutely non trivial and explaining it goes beyond the scope of this research. To implement this we will use the function “best_subset” That is returning the best model containing from one to six covariates. We therefore limit our comperison to the comparison between all the best subsets models that we can have.

allsub2 <- ols_step_best_subset(model)
allsub2

This seems to suggest a different results. All of these criteria are suggesting that the best model is the one with all six the explanatory variable with the exception of the SBC method, that again is suggesting the model with four variables as before. This discrepancy can be explained by the fact that, at least for the Akaike Information Criteria that we studied in class, the underlying constant C could dominate. This method is in fact more suitable for models with different dimensions |d|. (Notice also the the difference in AIC is very low: \(\Delta AIC = 2.59\) ) With small models AIC can easily prefer the complete model as the gain in “explained variance” obtained by adding a variable is more than the penalty introduced by that extra parameter.

We conclude this section by saying that the best model after this analysis is the one with four explanatory variable, obtained with the three step-wise method

Limitations of the study and Conclusions

Based on the results of our study, we can conclude that our last model explains quite well the variance in the data and that we collected about cancer and that some factors (for sure including the ones selected by us) are more influential than others in explaining the share of people suffering of cancer in a given country. Relatively older and richer countries (the two things often overlap) present many more cancer cases in percentage than the others and the same we can conclude of countries with a consumption of alcohol and cigarettes above the mean. However, our study has a lot of limitations that we have to indicate. - First, as we had to construct the data set by our own, we encountered some difficulties: we joined some data together into a table, but obviously we had some missing data. It’s not easy even just to collect the data in the same way for all the countries for more than 25 year for all those factors! - Secondly, we have to consider the difference in data availability that is present among the countries. To give an example: it’s much easier to find a data set about a given topic regarding the USA with respect to one regarding Burkina Faso. Besides that, we have taken into considerations just six factors to try to explain cancer incidence, but as we know it is a much more difficult research question: genetical heritage, other factors of concerning lifestyle, other environmental elements, access to the healthcare system, prevention and treatment offered by the country and many more things play a role in developing a cancer or not. - Moreover, it is not an ‘immediate’ disease: factors of risk sum up over the years and so do progress in medicine. This ends up in a complicated and intricate situation to analyze. Diving into some details, we also had a quite surprising result: the correlation between cancer cases and air pollution seems strongly negative, as the plot at the beginning shows. It is difficult to explain such a result, but it may be that since the worst quality of air is on average in less developed countries(eg. Nigeria, Pakistan, India…), it may be that other factors as the demographic distribution of the population or GDP, that typically obtain low values in those countries , have a stronger influence on the actual number of cancer cases, ending in this counter-intuitive result. The division that we made at the beginning seems to suggest that the “non-risk factors” are the one better suited to describe the distribution of cases worldwide, but again that’s what we wanted for this research: a merely descriptive approach. We conclude by saying that another interesting improvement to this research could be to trying to repeat the same analysis but just focusing on everyday habits and maybe by including the interaction effects within the possible covariates that we will choose in order to provide tips for an healthier routine.

->Hope many of you got the StatQuest tribute<-

LS0tCnRpdGxlOiAiRmluYWxQYXBlciBodG1sIHZlcnNpb24iCmF1dGhvcjogIkxvbGxvLCBQcmluY2UiCmRhdGU6ICI1LzEvMjAyMiIKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgdGhlbWU6IGpvdXJuYWwKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBkZl9wcmludDogcGFnZWQKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFKQpgYGAKCiMgSW50cm9kdWN0aW9uIGFuZCByZXNlYXJjaCBxdWVzdGlvbiAKCkxpZmUtRXhwZWN0YW5jeSBoYXMgY29uc3RhbnRseSBpbmNyZWFzZWQgb3ZlciB0aGUgbGFzdCBjZW50dXJpZXMsIGFuZCBpdCBoYXMgbmV2ZXIgYmVlbiBzbyBoaWdoIGFzIG5vd2FkYXlzLiBNZWRpY2luZSBoYXMgdGFrZW4gZ3JlYXQgc3RyaWRlcyBmb3J3YXJkLCBlcmFkaWNhdGluZyBhbmQgZmluZGluZyBjdXJlcyBmb3IgYSBsb3Qgb2YgbW9ydGFsIGRpc2Vhc2VzLiBIYXZpbmcgc2FpZCB0aGF0LCB0aGVyZSBhcmUgc3RpbGwgb3RoZXIgYmlnIGNoYWxsZW5nZXMgdGhhdCB3ZSBoYXZlIHRvIGZhY2UgaW4gbWVkaWNpbmUgYW5kIG9uZSBvZiB0aG9zZSBpcyBmb3Igc3VyZSBjYW5jZXIuIFtDYW5jZXIgaXMgYSBsZWFkaW5nIGNhdXNlIG9mIGRlYXRoIGFsbCBvdmVyIHRoZSB3b3JsZCwgYWNjb3VudGluZyBmb3IgYWxtb3N0IDEwIG1pbGxpb24gZGVhdGhzIGluIDIwMjBdKGh0dHBzOi8vd3d3Lndoby5pbnQvbmV3cy1yb29tL2ZhY3Qtc2hlZXRzL2RldGFpbC9jYW5jZXIpLiAKClRoaXMgaXMgdGhlIHJlYXNvbiB3aHkgd2UgdGhvdWdodCB0aGF0IHdvdWxkIGJlIHZlcnkgaW50ZXJlc3RpbmcgdG8gYW5hbHl6ZSB0aGUgcHJpbmNpcGFsIGZhY3RvcnMgdGhhdCwgYWNjb3JkaW5nIHRvIHN0YXRlLW9mLXRoZS1hcnQgc2NpZW50aWZpYyByZXNlYXJjaCwgIGNhdXNlIHRoaXMgZGlzZWFzZS4gV2UgYWxzbyB3YW50ZWQgdG8gZGl2aWRlIHRoZXNlIGZhY3RvcnMgaW50byBzb21lIG1hY3JvLWdyb3VwcyBvZiB2YXJpYWJsZXM6IGVudmlyb25tZW50YWwsIGxpZmVzdHlsZS1yZWxhdGVkLCBhbmQgc29jaW8tZWNvbm9taWNhbC9kZW1vZ3JhcGhpYy4gCgpPdXIgYW5hbHlzaXMgKHB1cmVseSBzdGF0aXN0aWNhbCkgYWltcyB0byB2ZXJpZnkgaWYgaXQgaXMgaW5kZWVkIHBvc3NpYmxlIHRvIHVzZSBkYXRhIGFib3V0IHRoZSBzZWxlY3RlZCByaXNrIGZhY3RvcnMgdG8gcHJlZGljdCB0aGUgc2hhcmUgb2YgcGVvcGxlIHdpdGggY2FuY2VyIGluIGEgIGdpdmVuIHllYXIgYW5kIGEgZ2l2ZW4gY291bnRyeS4gTW9yZW92ZXIsIHdlIHRyaWVkIHRvIGltcHJvdmUgb3VyIGFsbC1pbmNsdXNpdmUgbW9kZWwgYnkgZmluZGluZyB0aGUgYmVzdCBtb2RlbCBvdXQgb2YgdGhlIGFib3ZlLW1lbnRpb25lZCBmYWN0b3JzLiAKCgojIERhdGFzZXQsIERhdGEgQ2xlYW5pbmcgYW5kIERhdGEgVmlzdWFsaXphdGlvbgoKIyMgU291cmNlCgpPdXIgcmVzZWFyY2ggc3RhcnRlZCBieSBzZWFyY2hpbmcgb3V0IG9uIHNvbWUgcmVsaWFibGUgd2Vic2l0ZXMgd2hhdCBhcmUgdGhlIGxlYWRpbmcgY2F1c2VzIG9mIGNhbmNlciBhbmQgZGl2aWRpbmcgdGhlbSBpbnRvIHRoZSBtYWNyby1jYXRlZ29yaWVzLiBUbyBkbyB0aGF0IHdlIGFkb3B0ZWQgdGhlIFtXSE8gb2ZmaWNpYWwgd2Vic2l0ZV0oaHR0cHM6Ly93d3cud2hvLmludC9uZXdzLXJvb20vZmFjdC1zaGVldHMvZGV0YWlsL2NhbmNlcikgYW5kIHdlIHNlbGVjdGVkIHRoZSBmb2xsb3dpbmcgcmlzayBmYWN0b3JzOgoKLSAqRU5WSVJPTk1FTlRBTCo6IEFpciBwb2xsdXRpb24gCi0gKkxJRkUtU1RZTEUgUkVMQVRFRCo6IEFsY29ob2wgY29uc3VtcHRpb24sIFRvYmFjY28gY29uc3VtcHRpb24sIE9iZXNpdHkgCi0gKlNPQ0lPLUVDT05PTUlDQUwvREVNT0dSQVBISUMqOiBHRFAsIFNoYXJlIG9mIG9sZCBwZW9wbGUKCihJTVBPUlRBTlQgRElTQ0xBTUVSOiBvZiBjb3Vyc2UgdGhlIGZhY3RvcnMgZGVmaW5lZCB1bmRlciAiU29jaW8tRWNvbm9taWNhbC9EZW1vZ3JhcGhpYyIgY2Fubm90IGJlIGNvbnNpZGVyZWQgdG8gX19jYXVzZV9fIGNhbmNlciwgYnV0IGFzIHdlIHdpbGwgc2VlIHRoZXkgdHVybiBvdXQgdG8gYmUgdmVyeSB1c2VmdWwgdG8gbW9kZWwgY2FuY2VyIGFsbCBvdmVyIHRoZSB3b3JsZCBhbmQgb3ZlciB0aW1lKQoKIyMgRGVzY3JpcHRpb24gb2YgdGhlIHZhcmlhYmxlcwoKV2UgYnVpbHQgb3VyIGRhdGFzZXQgc2VsZWN0aW5nIGJ5IG1lcmdpbmcgZGlmZmVyZW50IGNzdiBmaWxlcyBhbGwgdGFrZW4gZnJvbSB0aGUgc2FtZSBzb3VyY2UsIHRoYXQgaXMgY2FsbGVkIFsiT3VyIHdvcmxkIGluIGRhdGEiXShodHRwczovL291cndvcmxkaW5kYXRhLm9yZy8pLiBUaGlzIGlzIGJ5IGl0c2VsZiBjb2xsZWN0aW5nIGRhdGFzZXRzIGZyb20gdmVyaWZpZWQgc291cmNlcyBhbmQgdGhlIHByZWNpc2UgcmVmZXJlbmNlIHRvIGVhY2ggZmFjdG9yIGlzIGdpdmVuIGluIHRoZSBzaXRvZ3JhcGh5IGF0IHRoZSBlbmQgb2YgdGhlIHBhcGVyLiBIZXJlIHdlIHByb3ZpZGUgYSBjb21wbGV0ZSBkZXNjcmlwdGlvbiBvZiB0aGUgdmFyaWFibGUgd2UgZGVjaWRlZCB0byB1c2UgaW4gb3VyIG1vZGVsLgoKKipDYW5jZXIqKjogU2hhcmUgb2YgdG90YWwgcG9wdWxhdGlvbiB3aXRoIGFueSBmb3JtIG9mIGNhbmNlciwgbWVhc3VyZWQgYXMgdGhlIGFnZS1zdGFuZGFyZGl6ZWQgcGVyY2VudGFnZS4gVGhpcwpzaGFyZSBoYXMgYmVlbiBhZ2Utc3RhbmRhcmRpemVkIGFzc3VtaW5nIGEgY29uc3RhbnQgYWdlIHN0cnVjdHVyZSB0byBjb21wYXJlIHByZXZhbGVuY2UgYmV0d2Vlbgpjb3VudHJpZXMgYW5kIHRocm91Z2ggdGltZS4KCioqQWlyX3BvbGx1dGlvbioqOiBQb3B1bGF0aW9uLXdlaWdodGVkIGF2ZXJhZ2UgbGV2ZWwgb2YgZXhwb3N1cmUgdG8gY29uY2VudHJhdGlvbnMgb2Ygc3VzcGVuZGVkCnBhcnRpY2xlcyBtZWFzdXJpbmcgbGVzcyB0aGFuIDIuNSBtaWNyb25zIGluIGRpYW1ldGVyIChQTTIuNSkuCkV4cG9zdXJlIGlzIG1lYXN1cmVkIGluIG1pY3JvIGdyYW1zIG9mIFBNMi41IHBlciBjdWJpYyBtZXRlciAowrVnL23CsykuCgoqKkFsY29ob2wqKjogQXZlcmFnZSBwZXIgY2FwdGEgY29uc3VtcHRpb24gb2YgYWxjb2hvbGljIGJldmVyYWdlcywgbWVhc3VyZWQgaW4ga2lsb2dyYW1zIHBlcgp5ZWFyLiBEYXRhIGlzIGJhc2VkIG9uIHBlciBjYXB0YSBmb29kIHN1cHBseSBhdCB0aGUgY29uc3VtZXIgbGV2ZWwsIGJ1dCBkb2VzIG5vdAphY2NvdW50IGZvciBmb29kIHdhc3RlIGF0IHRoZSBjb25zdW1lciBsZXZlbAoKKipHRFAgcGVyIGNhcHRhKio6IE1lYXN1cmVkIGluIGNvbnN0YW50IGludGVybmF0aW9uYWwtJAoKKipPYmVzaXR5Kio6IE9iZXNpdHkgaXMgZGVmaW5lZCBhcyBoYXZpbmcgYSBib2R5LW1hc3MgaW5kZXggKEJNSSkgZXF1YWwgdG8gb3IgZ3JlYXRlciB0aGFuIDMwLiBCTUkgaXMgYSBwZXJzb24ncwp3ZWlnaHQgaW4ga2lsb2dyYW1zIGRpdmlkZWQgYnkgaGlzIG9yIGhlciBoZWlnaHQgaW4gbWV0cmVzIHNxdWFyZWQKCioqT2xkIGFnZSBEZXBlbmRlbmN5Kio6IFRoaXMgaXMgdGhlIHJhdGlvIG9mIHRoZSBudW1iZXIgb2YgcGVvcGxlIG9sZGVyIHRoYW4gNjQgcmVsYXRpdmUgdG8gdGhlCm51bWJlciBvZiBwZW9wbGUgaW4gdGhlIHdvcmtpbmctYWdlICgxNS02NCB5ZWFycykuIERhdGEgYXJlIHNob3duIGFzCnRoZSBwcm9wb3J0aW9uIG9mIGRlcGVuZGVudHMgcGVyIDEwMCB3b3JraW5nLWFnZSBwb3B1bGF0aW9uLgoKKipTbW9raW5nKio6IFNoYXJlIG9mIHBvcHVsYXRpb24gd2hvIHNtb2tlIGV2ZXJ5IGRheQoKIyMgQ29uc3RydWN0aW5nIHRoZSB0YWJsZQpXZSBzdGFydGVkIGJ5IGxvYWRpbmcgYWxsIHRoZSBkaWZmZXJlbnQgY3N2IGZpbGVzLiBUaGVuIHdlIHRvb2sgdGhlIGNvbHVtbiB3ZSB3ZXJlIGludGVyZXN0ZWQgaW4gYW5kIHdlIGdsdWVkIHRoZW0gdG9nZXRoZXIuIEFmdGVyIHNvbWUgb3RoZXIgbGl0dGxlIG1hbmlwdWxhdGlvbiBoZXJlIGlzIGhvdyBwYXJ0IG9mIHRoZSBmaW5hbCB0YWJsZSBsb29rcyBsaWtlICh0aGUgY29tcGxldGUgdGFibGUgd2l0aCB0aGUgTi5BLnMgcmVzdWx0cyBpbiBhIGRpbWVuc2lvbiBvZiA2NDY4eDExKToKCmBgYHtyfQojI1dlIHN0YXJ0IGJ5IGxvYWRpbmcgc29tZSB1c2VmdWwgbGlicmFyaWVzIHRoYXQgd2Ugd2lsbCBuZWVkIGR1cmluZyB0aGlzIHByb2Nlc3MKCmxpYnJhcnkocmVhZHIpICNVc2VkIHRvIHJlYWQgdGhlIGNzdgpsaWJyYXJ5KHRpZHl2ZXJzZSkgI0NvbnRhaW5zIGEgbG90IG9mIHVzZWZ1bCBwYWNrYWdlcyB0byBjbGVhbiB0aGUgZGF0YXMKbGlicmFyeShnZ2FuaW1hdGUpICNUbyBjcmVhdGUgYW5pbWF0ZWQgcGxvdHMKbGlicmFyeShnZ3RoZW1lcykgI1RvIHNlbGVjdCBzb21lIG5pY2UgdGhlbWVzIApsaWJyYXJ5KHpvbykgI1RvIGZpbGwgdGhlIE4uQS4gdmFsdWVzIApsaWJyYXJ5KGdyaWQpICNUbyBkaXNwbGF5IHBsb3RzIGludG8gYSBncmlkCmxpYnJhcnkoZ3JpZEV4dHJhKSAjVG8gZGlzcGxheSBwbG90cyBpbnRvIGEgZ3JpZApsaWJyYXJ5KGdncHVicikjVG8gZGlzcGxheSBwbG90cyBpbnRvIGEgZ3JpZAoKIyNXZSBub3cgbG9hZCB0aGUgcm93IGNzdiBmaWxlcyB3aGF0IHdlIG5lZWQgdG8gbWVyZ2UgCgpDYW5jZXIgPC0gcmVhZF9jc3YoIkRhdGFzZXRzL0NhbmNlci5jc3YiKQpBaXJfcG9sbHV0aW9uIDwtIHJlYWRfY3N2KCJEYXRhc2V0cy9BaXIgcG9sbHV0aW9uLmNzdiIpCkFsY29vbCA8LSByZWFkX2NzdigiRGF0YXNldHMvQWxjb29sLmNzdiIpCkdEUF9wZXJfY2FwdGEgPC0gcmVhZF9jc3YoIkRhdGFzZXRzL0dEUCBwZXIgY2FwdGEuY3N2IikKT2Jlc2l0eSA8LSByZWFkX2NzdigiRGF0YXNldHMvT2Jlc2l0eS5jc3YiKQpPbGRfYWdlX2RlcGVuZGVuY3lfcmF0aW8gPC0gcmVhZF9jc3YoIkRhdGFzZXRzL09sZCBhZ2UgZGVwZW5kZW5jeSByYXRpby5jc3YiKQpTbW9raW5nIDwtIHJlYWRfY3N2KCJEYXRhc2V0cy9TbW9raW5nLmNzdiIpClBvcHVsYXRpb24gPC0gcmVhZF9jc3YoIkRhdGFzZXRzL3BvcHVsYXRpb24tc2luY2UtMTgwMC5jc3YiKQpjb3VudHJ5Q29udGluZW50IDwtIHJlYWRfY3N2KCJEYXRhc2V0cy9jb3VudHJ5Q29udGluZW50LmNzdiIpCgojV2UgcHJvY2VlZCBieSB0YWtpbmcgdGhlIGV4cGxhbmF0b3J5IHZhcmlhYmxlIGRhdGEgc2V0IChDYW5jZXIpIGFuZCBhZGRpbmcgdGhlIGNvdmFyaWF0ZXMgYXMgY29sdW1ucyBvdGhlciBjb2x1bW5zLCB0byBkbyB0aGF0IHdlIHVzZSB0aGUgdXNlIHRoZSBsaWJyYWJ5ICJkcGx5ciIgYXMgaXQgbWFrZXMgaXQgdmVyeSBlYXN5IHRvIGRvIGFuZCByZWFkYWJsZQoKQ29udGluZW50ID0gY291bnRyeUNvbnRpbmVudCAlPiUgc2VsZWN0KGNvdW50cnksIGNvbnRpbmVudCkKQ29udGluZW50dCA9IHJlbmFtZShDb250aW5lbnQsIEVudGl0eSA9IGNvdW50cnkpCkNhbmNlcjEgPSBsZWZ0X2pvaW4oQ2FuY2VyLCBBaXJfcG9sbHV0aW9uLCBieSA9IGMoIkVudGl0eSIsICJDb2RlIiwgIlllYXIiKSkKQ2FuY2VyMiA9IGxlZnRfam9pbihDYW5jZXIxLCBBbGNvb2wsIGJ5ID0gYygiRW50aXR5IiwgIkNvZGUiLCAiWWVhciIpKQpDYW5jZXIzID0gbGVmdF9qb2luKENhbmNlcjIsIEdEUF9wZXJfY2FwdGEsIGJ5ID0gYygiRW50aXR5IiwgIkNvZGUiLCAiWWVhciIpKQpDYW5jZXI0ID0gbGVmdF9qb2luKENhbmNlcjMsIE9iZXNpdHksIGJ5ID0gYygiRW50aXR5IiwgIkNvZGUiLCAiWWVhciIpKQpDYW5jZXI1ID0gbGVmdF9qb2luKENhbmNlcjQsIE9sZF9hZ2VfZGVwZW5kZW5jeV9yYXRpbywgYnkgPSBjKCJFbnRpdHkiLCAiQ29kZSIsICJZZWFyIikpCkNhbmNlcjYgPSBsZWZ0X2pvaW4oQ2FuY2VyNSwgU21va2luZywgYnkgPSBjKCJFbnRpdHkiLCAiQ29kZSIsICJZZWFyIikpCkNhbmNlcjcgPSBsZWZ0X2pvaW4oQ2FuY2VyNiwgQ29udGluZW50dCwgYnkgPSAiRW50aXR5IikKQ2FuY2VyX2ZpbmFsID0gQ2FuY2VyNwoKcm0oIkNhbmNlcjEiLCAiQ2FuY2VyMiIsICJDYW5jZXIzIiwgIkNhbmNlcjQiLCAiQ2FuY2VyNSIsICJDYW5jZXI2IiwgIkNhbmNlcjciKQpybSgiQWlyX3BvbGx1dGlvbiIsICJBbGNvb2wiLCAiQ2FuY2VyIiwgIkdEUF9wZXJfY2FwdGEiLCAiT2Jlc2l0eSIsICJPbGRfYWdlX2RlcGVuZGVuY3lfcmF0aW8iLCAiU21va2luZyIsICJDb250aW5lbnQiLCAiQ29udGluZW50dCIsICJjb3VudHJ5Q29udGluZW50IikKCiNXZSBub3cgcHJvY2VlZCBieSByZW5hbWluZyB0aGUgY29sdW1ucy4gVGhpcyB3aWxsIG1ha2UgYWxsIHRoZSBtYW5pcHVsYXRpb25zIG9mIHRoZSBkYXRhZnJhbWUgbW9yZSByZWFkYWJsZToKCmNvbG5hbWVzKENhbmNlcl9maW5hbClbNF0gPC0gIkNhbmNlciIKY29sbmFtZXMoQ2FuY2VyX2ZpbmFsKVs1XSA8LSAiQWlyUG9sbCIKY29sbmFtZXMoQ2FuY2VyX2ZpbmFsKVs2XSA8LSAiQWxjb29sIgpjb2xuYW1lcyhDYW5jZXJfZmluYWwpWzddIDwtICJHRFAiCmNvbG5hbWVzKENhbmNlcl9maW5hbClbOF0gPC0gIk9iZXNpdHkiCmNvbG5hbWVzKENhbmNlcl9maW5hbClbOV0gPC0gIkFnZSIKY29sbmFtZXMoQ2FuY2VyX2ZpbmFsKVsxMF0gPC0gIlNtb2tpbmciCgpDYW5jZXJfZmluYWwKd3JpdGUuY3N2KENhbmNlcl9maW5hbCwgIkNhbmNlcl9maW5hbC5jc3YiLCByb3cubmFtZXM9RkFMU0UsIHF1b3RlPUZBTFNFKSAjdG8gc2F2ZSB0aGUgZmlsZSBpbnRvIG91ciBlbnZpcm9ubWVudApgYGAKCiMjIERhdGEgVmlzdWFsaXphdGlvbgpOb3cgd2Ugd2lsbCBwcm9jZWVkIHdpdGggc29tZSBwbG90dGluZy4gQWdhaW4sIGZvciB0aGUgZGV0YWlsZWQgcHJvY2VzcyBmb3IgbWFraW5nIHRoaXMgZ3JhcGhzIHBsZWFzZSByZWZlciB0byB0aGUgUiBzY3JpcHQuIFlvdSBtYXkgYWxzbyB3YW50IHRvIGNoZWNrIG91ciBvdXIgZmlsZSBpbiBIdG1sIGZvcm1hdCwgaW4gd2hpY2ggd2UgbWFkZSBzb21lIG5pY2UgYW5pbWF0aW9uIHRvIGJlIGFibGUgdG8gZGlzcGxheSB0aGUgZXZvbHV0aW9uIGluIHRpbWUgb2YgdGhlIHZhcmlhYmxlcy4KCldlIHN0YXJ0IGJ5IGRpc3BsYXlpbmcgdGhlIHZhcmlhYmxlIHdlIGFyZSBpbnRlcmVzdGVkIHRvIGV4cGxhaW4sIHRoYXQgaXMgdGhlIHNoYXJlIG9mIHBvcHVsYXRpb24gd2l0aCBhbnkgZm9ybSBvZiBjYW5jZXIuIFdlIGNob3NlIHRvIHBsb3QgdGhlIG1vc3QgcmVjZW50IHllYXIgaW4gb3VyIGRhdGEgZnJhbWUsIHRoYXQgaXMgMjAxNy4gCkFzIHdlIGNhbiBjbGVhcmx5IHNlZSBmb3JtIHRoZSBwbG90IGJlbG93IHRoZSBjb3VudHJpZXMgaW4gd2hpY2ggYXJlIHN1ZmZlcmluZyBtb3JlIChpbiBwZXJjZW50YWdlKSBvZiBjYW5jZXIgYXJlIFVTQSwgQ2FuYWRhLCBBdXN0cmFsaWEgYW5kIEdyZWVubGFuZC4gVGhlc2Ugc3RhdGVzIGFyZSBmb2xsb3dlZCBieSBFdXJvcGVhbiBjb3VudHJpZXMuIEFzaWFuIGFuZCBBZnJpY2FuIGNvdW50cmllcyBhcmUgdGhlIG9uZXMgd2l0aCByZWxhdGl2ZWx5IGxlc3MgY2FzZXMgb2YgY2FuY2VyIGluIHBlcmNlbnRhZ2UuIApIZXJlIHdlIGNvdWxkIGFyZ3VlIHRoYXQgYSBiaWcgZG93bnNpZGUgb2YgdGhpcyBwaWN0dXJlIGlzIHRoZSBmYWN0IHRoYXQgZGlmZmVyZW50IGNvdW50cmllcyBoYXZlIGRpZmZlcmVudCBhYmlsaXR5IGluIHRoZSBwcm9jZXNzIG9mIHNjcmVlbmluZy4gQXMgdGhlIFdITyB3cml0ZXMgWyJMYXRlLXN0YWdlIHByZXNlbnRhdGlvbiBhbmQgbGFjayBvZiBhY2Nlc3MgdG8gZGlhZ25vc2lzIGFuZCB0cmVhdG1lbnQgYXJlIGNvbW1vbiwgcGFydGljdWxhcmx5IGluIGxvdy0gYW5kIG1pZGRsZS1pbmNvbWUgY291bnRyaWVzIl0oaHR0cHM6Ly93d3cud2hvLmludC9uZXdzLXJvb20vZmFjdC1zaGVldHMvZGV0YWlsL2NhbmNlcikgYW5kIHdlIHdpbGwgZnVydGhlciBkaXNjdXNzIHRoaXMgbGltaXRhdGlvbiBpbiB0aGUgZGVkaWNhdGVkIHNlY3Rpb24uCgooQ291bnRyaWVzIGZvciB3aGljaCBkYXRhIHdlcmUgbm90IGF2YWlsYWJsZSBhcmUgb21pdHRlZCBmcm9tIHRoZSBtYXAsIGJ1dCB0aG9zZSBhcmUgbHVja2lseSBmZXcpCgpgYGB7cn0KI1dlIHJlYWQgdGhlIGZpbGUgbmVlZGVkCnNoYXJlX29mX3BvcHVsYXRpb25fd2l0aF9jYW5jZXIgPC0gcmVhZF9jc3YoIkNhbmNlci5jc3YiKSAgI3JlYWQgdGhlIGZpbGUgCnNoYXJlX29mX3BvcHVsYXRpb25fd2l0aF9jYW5jZXIgPSBkYXRhLmZyYW1lKGxhcHBseShzaGFyZV9vZl9wb3B1bGF0aW9uX3dpdGhfY2FuY2VyLCBmdW5jdGlvbih4KSB7CiAgZ3N1YigiVW5pdGVkIFN0YXRlcyIsICJVU0EiLCB4KSAjY29ycmVjdGlvbiBuZWVkZWQgZm9yIHRoZSBtYXBwaW5nIAp9KSkKY29sbmFtZXMoc2hhcmVfb2ZfcG9wdWxhdGlvbl93aXRoX2NhbmNlcilbMV0gPC0gInJlZ2lvbiIgI0dpdmUgdGhlIHNhbWUgbmFtZSBmb3IgdGhlIGNvdW50cnkgaW4gdGhlIHR3byBkYXRhc2V0cwpjb2xuYW1lcyhzaGFyZV9vZl9wb3B1bGF0aW9uX3dpdGhfY2FuY2VyKVs0XSA8LSAiY2FuY2VyIiAjRHJvcHBpbmcgdGhlIGNvbXBsaWNhdGVkIG5hbWUgZ2l2ZW4gYnkgdGhlIGRhdGEgZnJhbWUKCiMgQ3JlYXRlIHRoZSBhY3R1YWwgbWFwIHRoYXQgd2Ugd2lsbCB1c2UKI1dlIHdpbGwgdXNlIHRoZSBnZ3BsbzIgcGFja2FnZSBmb3IgdGhhdAoKbWFwZGF0YSA9IG1hcF9kYXRhKCJ3b3JsZCIpICNVc2VkIHRvIHRha2UgdGhlIGxhdGl0dWRlIGFuZCBsb25naXR1ZGUgb2YgdGhlIGNvdW50cmllcyAKbWFwcCA8LSBtYXBkYXRhICU+JQogIGxlZnRfam9pbihzaGFyZV9vZl9wb3B1bGF0aW9uX3dpdGhfY2FuY2VyLCBieSA9ICJyZWdpb24iKSAjbWVyZ2UgdGhlIHR3byBkYXRhc2V0cwptYXBwMiA9IG1hcHAgJT4lIAogIGZpbHRlcighaXMubmEobWFwcCRjYW5jZXIpKSAjZGVhbGluZyB3aXRoIE5BCm1hcHAyJGNhbmNlciA8LSBhcy5udW1lcmljKG1hcHAyJGNhbmNlcikgI2NoYW5naW5nIHRoZSB2YWx1ZSB0byBudW1lcmljIGZvciBwbG90dGluZwptYXBwMiRZZWFyIDwtIGFzLm51bWVyaWMobWFwcDIkWWVhcikgI2NoYW5naW5nIHRoZSB2YWx1ZSB0byBudW1lcmljIGZvciBhbmltYXRpb24KYGBgCgoKYGBge3IsIGV2YWwgPSBGQUxTRX0KIyBCdWlsZGluZyB0aGUgbWFwCiNIZXJlIHdlIGNyZWF0ZSBhIHN0YXRpYyBtYXAKZ2dwbG90KCBkYXRhID0gbWFwcDIsIGFlcyhsb25nLCBsYXQsIGdyb3VwID0gc3VicmVnaW9uKSkgKwogIGdlb21fbWFwKAogICAgYWVzKG1hcF9pZCA9IHJlZ2lvbiksCiAgICBtYXAgPSBtYXBkYXRhLAogICAgY29sb3IgPSAiYmxhY2siLCBmaWxsID0gImdyYXkzMCIsIHNpemUgPSAwLjMKICApICsKICBnZW9tX3BvbHlnb24oYWVzKGdyb3VwID0gZ3JvdXAsIGZpbGwgPSBjYW5jZXIpLCBjb2xvciA9ICJibGFjayIpICsKICBzY2FsZV9maWxsX2dyYWRpZW50Mihsb3cgPSAiYmx1ZSIsIGhpZ2ggPSAicmVkIiAsIG1pZHBvaW50ID0gMS4wMzU1NTgzKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICB0cmFuc2l0aW9uX3RpbWUoWWVhcikKICBsYWJzKAogICAgdGl0bGUgPSAiU2hhcmUgb2YgcG9wdWxhdGlvbiB3aXRoIGNhbmNlciBpbiB7cm91bmQoZnJhbWVfdGltZX0iLAogICAgeCA9ICIiLCB5ID0gIiIsIGZpbGwgPSAiIgogICAgKSArCiAgdGhlbWVfYncoKQogIHNoYWRvd193YWtlKHdha2VfbGVuZ3RoID0gMC4wNSkKYW5pbWF0ZShncmFwaFBvbGwsIGhlaWdodCA9IDUwMCwgd2lkdGggPSA4MDAsIGZwcyA9IDMwLCBkdXJhdGlvbiA9IDE1LCBlbmRfcGF1c2UgPSA2MCwgcmVzID0gMTAwKQphbmltX3NhdmUoIlNoYXJlIHdpdGggY2FuY2VyIHdvcmxkLmdpZiIpCmBgYAoKIC0+IFRoaXMgaXMgbm90IHRoZSBmaWxlIHlvdSB3b3VsZCBnZXQgcnVubmluZyB0aGUgY29kZSwgYnV0IGl0cyBzdGF0aWMgdmVyc2lvbiwgTXkgY29tcHV0ZXIganVzdCBkb2Vzbid0IGhhdmUgZW5vdWdoIGNvbXB1dGF0aW9uYWwgcG93ZXIgdG8gcHJvZHVjZSB0aGlzIGFuaW1hdGlvbiBhbmQgc2h1dHMgZG93biB3aGVuIEkgdHJ5IHRvIGNyZWF0ZSB0aGUgYW5pbWF0aW9uIDogKAogaWYgeW91IHdhbnQgdG8gYnV5IG1lIGEgbmV3IE1hY0Jvb2sgUHJvIDE2Jycgd2l0aCB0aGUgTTEgTUFYIGNoaXAgZmVlbCBmcmVlIHRvIGNvbnRhY3QgbWUKIApgYGB7ciwgZWNobz1GQUxTRX0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIlNoYXJlIG9mIHBlb3BsZSB3aXRoIGNhbmNlciBpbiAyMDE3LmpwZyIpICNXZSB1c2UgaXQgdG8gZGlzcGxheSB0aGUgZ3JhcGhpYwpgYGAKCk5vdyB3ZSBhcmUgZ29pbmcgdG8gZXhwbG9yZSB0aGUgZGF0YXNldCBieSBwbG90dGluZyBlYWNoIHNlbGVjdGVkIGZhY3RvciBhZ2FpbnN0IHRoZSBDYW5jZXIgb25lIHRvIHN0YXJ0IGhhdmluZyBhbiBpZGVhIG9mIHNvbWUgcG9zc2libGUgcmVsYXRpb24uIEJlY2F1c2Ugd2Ugc2VsZWN0ZWQgdGhlbSBhcyAicmlzayBmYWN0b3JzIiB3ZSB3b3VsZCBleHBlY3QgdG8gc2VlIHNvbWUgcG9zaXRpdmUgY29ycmVsYXRpb24gZ29pbmcgb24uIFRvIGJlIGNvbnNpc3RlbnQgd2l0aCB3aGF0IHdlIGhhdmUgZG9uZSBhYm92ZSB3ZSBhZ2FpbiBwbG90IHRoZSBncmFwaHMgcmVsYXRpdmUgdG8gdGhlIHllYXIgMjAxNy4gV2UgYWxzbyB1c2VkIHNvbWUgbGlicmFyaWVzIHRvIG1ha2UgcGxvdHMgbmljZXIgYnkgY29sb3JpbmcgdGhlIHBvaW50cyBhY2NvcmRpbmcgdG8gdGhlIGNvbnRpbmVudCBhbmQgYnkgY2hhbmdpbmcgdGhlIHNpemUgYWNjb3JkaW5nIHRvIHRoZSBwb3B1bGF0aW9uIG9mIHRoZSBjb3VudHJ5LiAKClRoZSByZXN1bHQgaXMgdGhlIGZvbGxvd2luZzoKCmBgYHtyfQojSGVyZSB3ZSBjb3JyZWN0IHRoZSBOLkEucyBieSBmaWxsaW5nIHRoZSBjbG9zZXN0IG5vbiBlbXB0eSB2YWx1ZSAodGhpcyBpcyBuZWVkZWQgZm9yIHBsb3R0aW5nKQojYW5kIHdlIHdpbGwgbm90IGRvIGFueSBhbmFseXNpcyB3aXRoIHRoZXNlIGZha2UgZGF0YQpDYW5jZXJncmFwaCA9IGxlZnRfam9pbihDYW5jZXJfZmluYWwsIFBvcHVsYXRpb24sIGJ5ID0gYygiRW50aXR5IiwgIkNvZGUiLCAiWWVhciIpKQpDYW5jZXJncmFwaCRTbW9raW5nID0gbmEubG9jZihDYW5jZXJncmFwaCRTbW9raW5nKQpDYW5jZXJncmFwaCRBaXJQb2xsID0gbmEubG9jZihDYW5jZXJncmFwaCRBaXJQb2xsKQpDYW5jZXJncmFwaCRBbGNvb2wgPSBuYS5sb2NmKENhbmNlcmdyYXBoJEFsY29vbCkKQ2FuY2VyZ3JhcGgkR0RQID0gbmEubG9jZihDYW5jZXJncmFwaCRHRFAsIGZyb21MYXN0ID0gVFJVRSkKQ2FuY2VyZ3JhcGgkQWdlID0gbmEubG9jZihDYW5jZXJncmFwaCRBZ2UpCkNhbmNlcmdyYXBoJE9iZXNpdHkgPSBuYS5sb2NmKENhbmNlcmdyYXBoJE9iZXNpdHkpCkNhbmNlcmdyYXBoJGBQb3B1bGF0aW9uIChoaXN0b3JpY2FsIGVzdGltYXRlcylgID0gbmEubG9jZihDYW5jZXJncmFwaCRgUG9wdWxhdGlvbiAoaGlzdG9yaWNhbCBlc3RpbWF0ZXMpYCkKCmBgYAoKYGBge3IsIGV2YWw9RkFMU0V9CiNIZXJlIHdlIGNyZWF0ZSBhbmQgc2F2ZSBlYWNoIHBsb3QsIFRoaXMgY2h1bmsgb2YgY29kZSB3aWxsIG5vdCBiZSBldmFsdWF0ZWQgZXZlcnkgdGltZSBiZWNhdXNlIGlzIHByZXR0eSBoZWF2eSBhbmQgdGltZS9DUFUgY29uc3VtaW5nLiBUaGUgcmVzdWx0cyAodHJ1c3QgbWUpIGFyZSBpbmNsdWRlZCBhdCB0aGUgZW5kCmdyYXBoUG9sbCA9IENhbmNlcmdyYXBoICU+JQogIGdncGxvdChhZXMoeCA9IEFpclBvbGwsIHkgPSBDYW5jZXIsIGNvbG9yID0gY29udGluZW50LCBzaXplID0gYFBvcHVsYXRpb24gKGhpc3RvcmljYWwgZXN0aW1hdGVzKWApKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuOSwgc3Ryb2tlID0gMCkgKwogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDIsMTIpLCBndWlkZSA9ICJub25lIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArCiAgbGFicyh0aXRsZSA9ICJDYW5jZXIgaW5jaWRlbmNlIHZzIEFpciBQb2xsdXRpb24iLCAKICAgICAgIHggPSAiQWlyIHBvbGx1dGlvbiBleHBvc3VyZSAiLCAKICAgICAgIHkgPSAiU2hhcmUgb2YgcGVvcGxlIHdpdGggQ2FuY2VyIiwKICAgICAgIGNvbG9yID0gIkNvbnRpbmVudCIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogT3VyIFdvcmxkIGluIERhdGEiKSArCiAgdHJhbnNpdGlvbl90aW1lKFllYXIpICsKICBsYWJzIChzdWJ0aXRsZSA9ICJZZWFyOntyb3VuZChmcmFtZV90aW1lKX0iKSAKIHNoYWRvd193YWtlKHdha2VfbGVuZ3RoID0gMC4wNSkKYW5pbWF0ZShncmFwaFBvbGwsIGhlaWdodCA9IDUwMCwgd2lkdGggPSA4MDAsIGZwcyA9IDMwLCBkdXJhdGlvbiA9IDE1LCBlbmRfcGF1c2UgPSA2MCwgcmVzID0gMTAwKQphbmltX3NhdmUoIkFpcnBvbGwgVmlzdWFsIEFuaW1hdGlvbi5naWYiKQoKCmdyYXBoQWxjbyA9IENhbmNlcmdyYXBoICU+JQogIGdncGxvdChhZXMoeCA9IEFsY29vbCwgeSA9IENhbmNlciwgY29sb3IgPSBjb250aW5lbnQsIHNpemUgPSBgUG9wdWxhdGlvbiAoaGlzdG9yaWNhbCBlc3RpbWF0ZXMpYCkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC45LCBzdHJva2UgPSAwKSArCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoMiwxMiksIGd1aWRlID0gIm5vbmUiKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpICsKICBsYWJzKHRpdGxlID0gIkNhbmNlciBpbmNpZGVuY2UgdnMgQWxjb29sIGNvbnN1bXB0aW9uIiwgCiAgICAgICB4ID0gIkFsY29vbCBjb25zdW1lZCIsIAogICAgICAgeSA9ICJTaGFyZSBvZiBwZW9wbGUgd2l0aCBDYW5jZXIiLAogICAgICAgY29sb3IgPSAiQ29udGluZW50IiwKICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBPdXIgV29ybGQgaW4gRGF0YSIpICsKICB0cmFuc2l0aW9uX3RpbWUoWWVhcikgKwogIGxhYnMgKHN1YnRpdGxlID0gIlllYXI6e3JvdW5kKGZyYW1lX3RpbWUpfSIpIAogc2hhZG93X3dha2Uod2FrZV9sZW5ndGggPSAwLjA1KQphbmltYXRlKGdyYXBoQWxjbywgaGVpZ2h0ID0gNTAwLCB3aWR0aCA9IDgwMCwgZnBzID0gMzAsIGR1cmF0aW9uID0gMTUsIGVuZF9wYXVzZSA9IDYwLCByZXMgPSAxMDApCmFuaW1fc2F2ZSgiQWxjb29sIFZpc3VhbCBBbmltYXRpb24uZ2lmIikKCgpncmFwaEdEUCA9IENhbmNlcmdyYXBoICU+JQogIGdncGxvdChhZXMoeCA9IEdEUCwgeSA9IENhbmNlciwgY29sb3IgPSBjb250aW5lbnQsIHNpemUgPSBgUG9wdWxhdGlvbiAoaGlzdG9yaWNhbCBlc3RpbWF0ZXMpYCkpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC45LCBzdHJva2UgPSAwKSArCiAgc2NhbGVfc2l6ZShyYW5nZSA9IGMoMiwxMiksIGd1aWRlID0gIm5vbmUiKSArCiAgc2NhbGVfY29sb3JfYnJld2VyKHBhbGV0dGUgPSAiU2V0MiIpICsKICBsYWJzKHRpdGxlID0gIkNhbmNlciBpbmNpZGVuY2UgdnMgR0RQIiwgCiAgICAgICB4ID0gIkdEUCBwZXIgY2FwdGEiLCAKICAgICAgIHkgPSAiU2hhcmUgb2YgcGVvcGxlIHdpdGggQ2FuY2VyIiwKICAgICAgIGNvbG9yID0gIkNvbnRpbmVudCIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogT3VyIFdvcmxkIGluIERhdGEiKSArCiAgdHJhbnNpdGlvbl90aW1lKFllYXIpICsKICBsYWJzIChzdWJ0aXRsZSA9ICJZZWFyOntyb3VuZChmcmFtZV90aW1lKX0iKSAKIHNoYWRvd193YWtlKHdha2VfbGVuZ3RoID0gMC4wNSkKYW5pbWF0ZShncmFwaEdEUCwgaGVpZ2h0ID0gNTAwLCB3aWR0aCA9IDgwMCwgZnBzID0gMzAsIGR1cmF0aW9uID0gMTUsIGVuZF9wYXVzZSA9IDYwLCByZXMgPSAxMDApCmFuaW1fc2F2ZSgiR0RQIFZpc3VhbCBBbmltYXRpb24uZ2lmIikKCgpncmFwaE9iZXMgPSBDYW5jZXJncmFwaCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBPYmVzaXR5LCB5ID0gQ2FuY2VyLCBjb2xvciA9IGNvbnRpbmVudCwgc2l6ZSA9IGBQb3B1bGF0aW9uIChoaXN0b3JpY2FsIGVzdGltYXRlcylgKSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjksIHN0cm9rZSA9IDApICsKICBzY2FsZV9zaXplKHJhbmdlID0gYygyLDEyKSwgZ3VpZGUgPSAibm9uZSIpICsKICBzY2FsZV9jb2xvcl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQyIikgKwogIGxhYnModGl0bGUgPSAiQ2FuY2VyIGluY2lkZW5jZSB2cyBPYmVzaXR5IiwgCiAgICAgICB4ID0gIlNoYXJlIG9mIE9iZXNlIHBlb3BsZSIsIAogICAgICAgeSA9ICJTaGFyZSBvZiBwZW9wbGUgd2l0aCBDYW5jZXIiLAogICAgICAgY29sb3IgPSAiQ29udGluZW50IiwKICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBPdXIgV29ybGQgaW4gRGF0YSIpICsKICB0cmFuc2l0aW9uX3RpbWUoWWVhcikgKwogIGxhYnMgKHN1YnRpdGxlID0gIlllYXI6e3JvdW5kKGZyYW1lX3RpbWUpfSIpIAogc2hhZG93X3dha2Uod2FrZV9sZW5ndGggPSAwLjA1KQphbmltYXRlKGdyYXBoT2JlcywgaGVpZ2h0ID0gNTAwLCB3aWR0aCA9IDgwMCwgZnBzID0gMzAsIGR1cmF0aW9uID0gMTUsIGVuZF9wYXVzZSA9IDYwLCByZXMgPSAxMDApCmFuaW1fc2F2ZSgiT2Jlc2l0eSBWaXN1YWwgQW5pbWF0aW9uLmdpZiIpCgoKZ3JhcGhBZ2UgPSBDYW5jZXJncmFwaCAlPiUKICBnZ3Bsb3QoYWVzKHggPSBBZ2UsIHkgPSBDYW5jZXIsIGNvbG9yID0gY29udGluZW50LCBzaXplID0gYFBvcHVsYXRpb24gKGhpc3RvcmljYWwgZXN0aW1hdGVzKWApKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuOSwgc3Ryb2tlID0gMCkgKwogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDIsMTIpLCBndWlkZSA9ICJub25lIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArCiAgbGFicyh0aXRsZSA9ICJDYW5jZXIgaW5jaWRlbmNlIHZzIEFnZSIsIAogICAgICAgeCA9ICJPbGQgcGVvcGxlIHJhdGlvIiwgCiAgICAgICB5ID0gIlNoYXJlIG9mIHBlb3BsZSB3aXRoIENhbmNlciIsCiAgICAgICBjb2xvciA9ICJDb250aW5lbnQiLAogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IE91ciBXb3JsZCBpbiBEYXRhIikgKwogIHRyYW5zaXRpb25fdGltZShZZWFyKSArCiAgbGFicyAoc3VidGl0bGUgPSAiWWVhcjp7cm91bmQoZnJhbWVfdGltZSl9IikgCiBzaGFkb3dfd2FrZSh3YWtlX2xlbmd0aCA9IDAuMDUpCmFuaW1hdGUoZ3JhcGhBZ2UsIGhlaWdodCA9IDUwMCwgd2lkdGggPSA4MDAsIGZwcyA9IDMwLCBkdXJhdGlvbiA9IDE1LCBlbmRfcGF1c2UgPSA2MCwgcmVzID0gMTAwKQphbmltX3NhdmUoIkFnZSBWaXN1YWwgQW5pbWF0aW9uLmdpZiIpCgoKZ3JhcGhTbW9rZSA9IENhbmNlcmdyYXBoICU+JQogIGdncGxvdChhZXMoeCA9IFNtb2tpbmcsIHkgPSBDYW5jZXIsIGNvbG9yID0gY29udGluZW50LCBzaXplID0gYFBvcHVsYXRpb24gKGhpc3RvcmljYWwgZXN0aW1hdGVzKWApKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuOSwgc3Ryb2tlID0gMCkgKwogIHNjYWxlX3NpemUocmFuZ2UgPSBjKDIsMTIpLCBndWlkZSA9ICJub25lIikgKwogIHNjYWxlX2NvbG9yX2JyZXdlcihwYWxldHRlID0gIlNldDIiKSArCiAgbGFicyh0aXRsZSA9ICJDYW5jZXIgaW5jaWRlbmNlIHZzIFNtb2tpbmciLCAKICAgICAgIHggPSAiTnVtYmVyIG9mIFNtb2tlcnMiLCAKICAgICAgIHkgPSAiU2hhcmUgb2YgcGVvcGxlIHdpdGggQ2FuY2VyIiwKICAgICAgIGNvbG9yID0gIkNvbnRpbmVudCIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogT3VyIFdvcmxkIGluIERhdGEiKSArCiAgdHJhbnNpdGlvbl90aW1lKFllYXIpICsKICBsYWJzIChzdWJ0aXRsZSA9ICJZZWFyOntyb3VuZChmcmFtZV90aW1lKX0iKSAKIHNoYWRvd193YWtlKHdha2VfbGVuZ3RoID0gMC4wNSkKYW5pbWF0ZShncmFwaFNtb2tlLCBoZWlnaHQgPSA1MDAsIHdpZHRoID0gODAwLCBmcHMgPSAzMCwgZHVyYXRpb24gPSAxNSwgZW5kX3BhdXNlID0gNjAsIHJlcyA9IDEwMCkKYW5pbV9zYXZlKCJTbW9raW5nIFZpc3VhbCBBbmltYXRpb24gMy5naWYiKQoKYGBgCgoKYGBge3J9CiNBbmQgZXZlbnR1YWxseSBoZXJlIGl0IGlzIHRoZSBhbmltYXRpb25zOgprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQWlycG9sbCBWaXN1YWwgQW5pbWF0aW9uLmdpZiIpCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJBbGNvb2wgVmlzdWFsIEFuaW1hdGlvbi5naWYiKQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiR0RQIFZpc3VhbCBBbmltYXRpb24uZ2lmIikKa25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIk9iZXNpdHkgVmlzdWFsIEFuaW1hdGlvbi5naWYiKQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQWdlIFZpc3VhbCBBbmltYXRpb24uZ2lmIikKa25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIlNtb2tpbmcgVmlzdWFsIEFuaW1hdGlvbiAzLmdpZiIpCmBgYAoKCk91ciBoeXBvdGhlc2lzIGlzIGNvbmZpcm1lZCBieSB0aGVzZSBncmFwaHM6IGV2aWRlbnRseSB0aGVyZSdzIHNvbWUgc29ydCBvZiBwb3NpdGl2ZSBjb3JyZWxhdGlvbiwgYnV0IHN0aWxsIG5vdCBzdHJvbmcgYXMgd2UgaW1hZ2luZWQgYmVmb3JlaGFuZC4gV2UgY2FuIHNlZSB0aGF0IGFnZSBpcyB0aGUgZmFjdG9yIHdoaWNoIHByZXNlbnRzIGEgc3Ryb25nZXIgY29ycmVsYXRpb24gdmlzdWFsbHkuVGhlIG9ubHkgcHJvYmxlbSBpcyB0aGUgb25lIHJlbGF0ZWQgdG8gQWlyIHBvbGx1dGlvbi4gT3VyIGV4cGxhbmF0aW9uIGZvciB0aGF0IGlzIHRoYXQgd2lsbCBiZSBwcm92aWRlZCBpbiB0aGUgc2VjdGlvbiAiTGltaXRhdGlvbnMgb2YgdGhlIHN0dWR5Ii4KCldlIGFsc28gaGF2ZSBzb21lIG91dGxpZXJzLCB3aGljaCBhcmUgQ2FuYWRhIGFuZCBVUyAoVGhlIHR3byBvcmFuZ2UgcG9pbnRzIHRoYXQgb24gZWFjaCBncmFwaCBhcmUgYWJvdmUgdGhlIG90aGVycykuIEJlaW5nIGNhbmNlciBjYXVzZXMgc3VjaCBhIGNvbXBsaWNhdGVkIGFuZCBpbnRyaWNhdGUgdGhpbmcsIGlzIGFjdHVhbGx5IHF1aXRlIGRpZmZpY3VsdCB0byByZWFsbHkgdW5kZXJzdGFuZCB3aHkgdGhvc2UgdHdvIGNvdW50cmllcyBoYXZlIHN1Y2ggYW4gaGlnaCBudW1iZXIgb2YgY2FzZXMuIFdlIGNhbiBzdXBwb3NlIHRoYXQgdGhlc2UgdHdvIGNvdW50cmllcyBwZXJmb3JtIGEgbW9yZSBpbnRlbnNlIHNjcmVlbmluZyBhY3Rpdml0eSwgYnV0IHRoaXMgZ29lcyBiZXlvbmQgdGhlIHNjb3BlIG9mIHRoaXMgc3R1ZHkuIFdlIHdpbGwganVzdCBkZWxldGUgdGhlc2UgdHdvIGNvdW50cmllcyBmcm9tIG91ciBkYXRhIHNldC4gSGF2aW5nIHNhaWQgdGhhdCwgdGhlIHJlc3VsdCB0aGF0IGZvbGxvdyB3aWxsIGJlIG5vdCBzaWduaWZpY2FudGx5IGNoYW5nZWQgYnkgdGhpcyBhY3Rpb24uCgojIE11bHRpdmFyaWF0ZSBMaW5lYXIgUmVncmVzc2lvbgoKV2UgYXJlIG5vdyBnb2luZyB0byBwZXJmb3JtIGEgbXVsdGl2YXJpYXRlIGxpbmVhciByZWdyZXNzaW9uLCAgdHJ5aW5nIHRvIGV4YW1pbmUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHNvbWUgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGFuZCBvbmUgcmVzcG9uc2UgdmFyaWFibGUuIEFzIG1lbnRpb25lZCBiZWZvcmUsIHdlIGFyZSBnb2luZyB0byB0YWtlIGludG8gY29uc2lkZXJhdGlvbiBhcyBleHBsYW5hdG9yeSB2YXJpYWJsZXMgYWxsIHRoZSBmYWN0b3JzIHNlbGVjdGVkIHRvIGhlbHAgdXMgdHJ5IHRvIGV4cGxhaW4gcGFydCBvZiB0aGUgdmFyaWFuY2Ugb2YgdGhlIHNoYXJlIG9mIHBlb3BsZSBhZmZlY3RlZCBieSBjYW5jZXIgd29ybGR3aWRlLiBUaGUgdGFibGUgdXNlZCBpcyBjb25zaWRlcmluZyBhcHByb3hpbWF0ZWx5IDE1MCBjb3VudHJpZXMgZm9yIGFwcHJveGltYXRlbHkgMjAgeWVhcnMuIEluIHRoaXMgd2F5LCB3ZSB3aWxsIGJlIGFibGUgdG8gZG8gbm90IG1pc3Mgc29tZSB0cmVuZCBvciB0byBkbyBub3QgYmUgZGVjZWl2ZWQgYnkgc29tZSBvdXRsaWVycyB5ZWFycy9jb3VudHJpZXMgb3IgcmFuZG9tIHRyZW5kcy4KCk5vdywgbGV04oCZcyBwcm9jZWVkIHdpdGggcGVyZm9ybWluZyB0aGUgYWN0dWFsIG11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uLiBBZnRlciB0aGF0LCB3ZSB3YW50IHRvIHNlZSBpZiB0aGUgYXNzdW1wdGlvbnMgcmVxdWlyZWQgdG8gc3RhdGUgdGhlIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZSBhcmUgbWV0OiB3ZeKAmWxsIGNoZWNrIGZvciB0aGUgbm9ybWFsaXR5IGFuZCB0aGUgaG9tb3NjZWRhc3RpY2l0eSBvZiB0aGUgcmVzaWR1YWxzLgoKCmBgYHtyfQpsaWJyYXJ5KG9sc3JyKQoKIyBEZWxldGUgdGhlIE4uQS5zCm15ZGF0YSA9IHJlYWQuY3N2KCJDYW5jZXJfZmluYWwuY3N2IikKZGF0YTUgPSBuYS5vbWl0KG15ZGF0YSkKCiMgRGVsZXRlIFVTQSBhbmQgQ2FuYWRhIGZyb20gdGhlIGRhdGEgc2V0CmRhdGEzID0gc3Vic2V0KGRhdGE1LCBFbnRpdHkgIT0gIlVTQSIpCgojTm9ybWFsaXR5IG9mIHRoZSByZXNpZHVhbHMKbW9kZWwgPSBsbSggQ2FuY2VyfiBTbW9raW5nICsgT2Jlc2l0eSArIEdEUCArIEFnZSArIEFpclBvbGwgKyBBbGNvb2wsIGRhdGEgPSBkYXRhMykKCiNQZXJmb3JtIFRlc3RpbmcgZm9yIG5vcm1hbGl0eSBvZiByZXNpZHVhbHMKb2xzX3Rlc3Rfbm9ybWFsaXR5KG1vZGVsKQoKI3Bsb3QgaGlzdG9ncmFtIG9mIHJlc2lkdWFscwprb3AgPSByZXNpZHVhbHMubG0obW9kZWwpCmhpc3Qoa29wLCBicmVha3MgPSA1MCkKCiNDaGVjayBncmFwaGljYWxseSB1c2luZyB0aGUgZnVuY3Rpb24gcGxvdApwbG90KG1vZGVsKQoKYGBgCgpMZXTigJlzIGFuYWx5emUgZWFjaCBvZiB0aGUgdGVzdCB3ZSBwZXJmb3JtZWQgYWJvdmUgYW5kIHNlZSB3aGljaCBjb25jbHVzaW9uIHdlIGNhbiB0YWtlIGZyb20gd2hhdCB3ZSBvYnNlcnZlZC4gCkZvciB3aGF0IGNvbmNlcm5zIG5vcm1hbGl0eSBvZiB0aGUgcmVzaWR1YWxzLCB3ZSBjYW4gc2VlIHRoYXQgdGhlIHAtdmFsdWUgb2YgdGhlIHRlc3RzIHdlIHBlcmZvcm1lZCBpcyBiZWxvdyB0aGUgMC4wNSBzaWduaWZpY2FuY2UgbGV2ZWwgZm9yIGFsbCBvZiB0aGVtLCB0aHVzIHdlIGNhbiByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHRoZSBlcnJvcnMgYXJlIG5vcm1hbGx5IGRpc3RyaWJ1dGVkLiBUaGlzIGlzIGV4YWN0bHkgYXMgd2UgaW1hZ2luZWQ6IHRoZSBkYXRhIHNldCBpcyBtYWRlIGJ5IG1vcmUgb3IgbGVzcyAgMTAwMCBkYXRhIHBvaW50cywgdGh1cyB2aW9sYXRpbmcgdGhpcyBhc3N1bXB0aW9uIHdhcyBzb21ldGhpbmcgdGhhdCB3ZSBleHBlY3RlZCBmb3IuIFRoaXMgaXMgZHVlIHRvIHRoZSBmYWN0IHRoYXQgd2l0aCB0aGlzIG1hbnkgZGF0YSBwb2ludHMgaXQncyBlYXN5IGZvciB0aGUgdGVzdGluZyBtZXRob2RzIHRvIGZpbmQgZXZpZGVuY2UgYWdhaW5zdCBub3JtYWxpdHkuClRyeWluZyB0byBzZWUgdGhlIHNpdHVhdGlvbiBncmFwaGljYWxseSwgdGhlIHNpdHVhdGlvbnMgc2VlbXMgYSBiaXQgYmV0dGVyLiBUaGUgcXEtcGxvdCBzaG93cyB0aGF0IHRoZSBkYXRhIGZpdCBub3QgdGhhdCBiYWRseSB0aGUgZGlhZ29uYWwgbGluZSwgZXhjZXB0aW9ucyBtYWRlIGZvciBhIGxpdHRsZSBkZXZpYXRpb24gbmVhciB0aGUgdG9wLXJpZ2h0LiBGdXJ0aGVybW9yZSwgYW5hbHl6aW5nIGFub3RoZXIgZ3JhcGggd2Ugc2VlIHRoYXQgcGxvdHRpbmcgdGhlIHJlc2lkdWFscyBhZ2FpbnN0IHRoZSBmaXR0ZWQgdmFsdWVzIGFwcHJveGltYXRlcyBtb3JlIG9yIGxlc3MgYSBzdHJhaWdodCBsaW5lLiBUaGUgYW5hbHlzaXMgb2YgdGhlIHJlc2lkdWFscyBpcyBlbm91Z2ggc2F0aXNmeWluZywgYnV0IGlmIHdlIHdhbnQgdG8gYmUgc3RyaWN0IHdlIHdpbGwgc2F5IHRoYXQgd2UgYXJlIG5vdCBhYmxlIHRvIHRha2Ugb3V0IGFueSBzaWduaWZpY2FudCBjb25jbHVzaW9ucyBmcm9tIHRoZSBleHBlcmltZW50IHdlIHdpbGwgY2Fycnkgb24uCgpXZSBub3cgcGVyZm9ybSBhbmQgaW50ZXJwcmV0IHRoZSByZXN1bHQgb2YgdGhlIG11bHRpcGxlIGxpbmVhciByZWdyZXNzaW9uIGl0c2VsZi4KCmBgYHtyfQpzdW1tYXJ5KG1vZGVsKQpgYGAKCkZyb20ganVzdCB0aGVzZSByZXN1bHRzLCB3ZSBjYW4gc2VlIHZhcmlvdXMgdGhpbmdzOiB0aGUgdmFsdWUgb2YgdGhlIEFkanVzdGVkIFItU3F1YXJlZCBpcyB2ZXJ5IHNhdGlzZnlpbmcsIGFuZCB0aGVuIHRoaXMgbW9kZWwgZml0cyBwcmV0dHkgd2VsbCB0aGUgZGF0YSwgdGVsbGluZyB1cyB0aGVyZSBpcyBhIHF1aXRlIGdvb2QgCnJlbGF0aW9uc2hpcCB3aXRoIHRoZSBjb3ZhcmlhdGVzIHdlIGluZGljYXRlZDogb3VyIGZhY3RvcnMgZXhwbGFpbiBhIDgyJSB2YXJpYW5jZSBpbiAgdGhlIHNoYXJlIG9mIHBvcHVsYXRpb24gd2l0aCBjYW5jZXIhIFdlIGFyZSBhY3R1YWxseSBjb25zaWRlcmluZyB0aGUgQWRqdXN0ZWQgUi1TcXVhcmVkIHNpbmNlIHdlIGFyZSBwZXJmb3JtaW5nIGEgbXVsdGl2YXJpYXRlIGxpbmVhciByZWdyZXNzaW9uLCBhbmQgdGh1cyB0aGUgbnVtYmVyIG9mIGZhY3RvcnMgd2UgaW5jbHVkZSBpbiBvdXIgbW9kZWwgaXMgcmVsZXZhbnQgYW5kIHdlIHdhbnQgdG8gcGVuYWxpemUgYmlnZ2VyIG1vZGVscy4gSW4gZmFjdCB3ZSBrbm93IHRoYXQgdGhlIHNpbXBseSB2YWx1ZSBvZiBSLVNxdWFyZWQgY2FuIGp1c3QgaW5jcmVhc2Ugd2hlbiBhZGRpbmcgbW9yZSBmYWN0b3JzLCBldmVuIGlmIHRob3NlIGFyZSBjb21wbGV0ZWx5IHJhbmRvbSBvbmVzLiAKSW4gYWRkaXRpb24sIGFsbCB0aGUgdmFyaWFibGVzIHNlZW0gdG8gZXhwbGFpbiBwcmV0dHkgd2VsbCB0aGUgc2hhcmUgb2YgY2FuY2VyIGNhc2VzOmFsbW9zdCBhbGwgb2YgdGhlIHAtdmFsdWVzIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50ISBUaGUgb25seSBleGNlcHRpb24gaXMgZ2l2ZW4gYnkgdGhlICJPYmVzaXR5IiBleHBsYW5hdG9yeSB2YXJpYWJsZS4KCgojIE1vZGVsIFNlbGVjdGlvbiAoVGVzdGluZykKCk5vdyB0aGF0IHdlIGRpc2N1c3NlZCB0aGUgbGluZWFyIG1vZGVsIGFuZCB0aGUgdW5kZXJseWluZyBjaGFyYWN0ZXJpc3RpY3MsIHdlIHdhbnQgdG8gZG8gc29tZSBiYXNpYyBtb2RlbCBzZWxlY3Rpb24gdG8gc2VlIGlmIHRoZXJlIGFyZSBvdGhlciBtb2RlbHMgKHBvc3NpYmx5IHNpbXBsZXIpIHRoYXQgYXJlIGFibGUgdG8gZXhwbGFpbiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIHdlbGwgZW5vdWdoLiBUbyBkbyB0aGF0IHdlIHdpbGwgbGV2ZXJhZ2Ugb24gdHdvIGRpZmZlcmVudCBhcHByb2FjaCB0byBtb2RlbCBzZWxlY3Rpb24uIFRoZSBmaXJzdCBpcyB0aGUgb25lIHByb3ZpZGVkIGJ5IHRlc3RpbmcgYW5kIHRoZSBvdGhlciB0aGUgb25lIHByb3ZpZGVkIGJ5IGluZm9ybWF0aW9uIHRoZW9yeS4gV2Ugd2lsbCBjb21wYXJlIHRoZSByZXN1bHRzIGFuZCBzZWUgd2hldGhlciB0aGV5IGNvaW5jaWRlIG9yIG5vdC4KCgpXZSBzdGFydCBieSBpbXBvcnRpbmcgdGhlIGRhdGEgd2Ugd2lsbCBuZWVkIGZvciB0aGUgbW9kZWwgc2VsZWN0aW9uIGFuZCBsb2FkaW5nIHNvbWUgdXNlZnVsIGxpYnJhcmllcy4gV2Ugd2lsbCB0aGVuIGNyZWF0ZSBvdXIgbGluZWFyIG1vZGVsIHVzaW5nIGFsbCB0aGUgY292YXJpYXRlcyBhbmQgdGhlIGRhdGFzZXQgd2l0aG91dCB0aGUgbWlzc2luZyB2YWx1ZXMgKHdlIHdpbGwgdXNlIHRoZSBzYW1lIG1vZGVsIG9idGFpbmVkIGFib3ZlIHdpdGggdGhlIHJlZ3Jlc3Npb24pCgpgYGB7cn0KbGlicmFyeShvbHNycikgI1RoaXMgc3RhbmRzIGZvciBPcmRpbmFyeSBMZWFzdCBTcXVhUmUgUmVncmVzc2lvbiBhbmQgaXQgaGFzIHRoZSB0b29scyBuZWVkZWQKbW9kZWwgPSBsbSggQ2FuY2VyIH4gU21va2luZyArIE9iZXNpdHkgKyBHRFAgKyBBZ2UgKyBBaXJQb2xsICsgQWxjb29sLCBkYXRhID0gZGF0YTMpCnN1bW1hcnkobW9kZWwpCmBgYAoKV2UgYmVnaW4gYnkgdHJ5aW5nIHRocmVlIGRpZmZlcmVudCB0ZXN0aW5nIG1ldGhvZHMsIGNhbGxlZCByZXNwZWN0aXZlbHkgIlN0ZXAtdXAvRm9yd2FyZCIsICJTdGVwLWRvd24vQmFja3dhcmQiIGFuZCAiU3RlcC1ib3RoIi4gVGhlIGZpc3QgdHdvIGFjdCBpbiBhIGR1YWwgd2F5IHdpdGggcmVzcGVjdCB0byB0aGUgc2Vjb25kIGFuZCB0aGUgbGFzdCBpcyBpbiBhIHdheSBhYmxlIHRvIG92ZXJjb21lIHRoZSBkb3duc2lkZXMgb2YgdGhlIGZpcnN0IHR3byBtb2RlbHMuIFdpdGhvdXQgZW50ZXJpbmcgdG9vIG11Y2ggaW50byB0aGUgZGV0YWlscyB0aGlzIGdyZWVkeSBtZXRob2RvbG9neSBzdGFydHMgd2l0aCBubyhhbGwpIHByZWRpY3RvcnMgaW4gdGhlIG1vZGVsIGFuZCBpdGVyYXRpdmVseSBhZGQoc3VidHJhY3QpIHRoZSBvbmUgdGhhdCBpcyBtb3JlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgaW4gY29udHJpYnV0aW5nIHRvIHRoZSBtb2RlbC4gVGhlIHByb2NlZHVyZSBhdXRvbWF0aWNhbGx5IHN0b3BzIHdoZW4gbm8gb3RoZXIgdmFyaWFibGVzIGNhbiBiZSBhZGRlZCB0byBnYWluIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZS4gSW4gcHJhY3RpY2Ugd2hhdCB3ZSBkbyBhdCBlYWNoIHN0ZXAgaXMgdG8gcGVyZm9ybSBhIHQtdGVzdCBmb3IgZWFjaCBjYW5kaWRhdGUgdmFyaWFibGUgYW5kIHNlZSB3aGljaCBvbmUgaGFzIHRoZSBsb3dlc3QgcC12YWx1ZSAoaWYgdGhlcmUgaXMgb25lKS4gSW4gdGhpcyBzZXR0aW5nIHdlIGtlcHQgYSBzaWduaWZpY2FuY2UgbGV2ZWwgb2YgMC4wNSBib3RoIGZvciBlbnRlcmluZyBhbmQgZm9yIGV4aXRpbmcgdGhlIG1vZGVsLgoKVGhlIFN0ZXAtdXAgbWV0aG9kIHlpZWxkczoKYGBge3J9CmZyd2ZpdCA8LSBvbHNfc3RlcF9mb3J3YXJkX3AobW9kZWwsIHBlbnQgPSAwLjA1KQpmcndmaXQKYGBgCgpUaGUgc2VsZWN0aW9uIGxlZCB1cyB0byBhZGQgdG8gdGhlIG1vZGVsIHRoZSAiQWdlIiwgIkdEUCIsICJBaXJwb2xsIiBhbmQgIkFsY29vbCIuIFdlIG5vdyB0cnkgdGhlIHN5bW1ldHJpY2FsIG1ldGhvZCwgCgpUaGUgU3RlcC1kb3duIG1ldGhvZCB5aWVsZHM6CmBgYHtyfQpia3dmaXQgPC0gb2xzX3N0ZXBfYmFja3dhcmRfcChtb2RlbCwgcHJlbSA9IDAuMDUpCmJrd2ZpdApgYGAKCkFzIHlvdSBjYW4gc2VlIHdlIGdvdCB0aGUgc2FtZSByZXN1bHQgaGVyZTogd2UgcmVqZWN0ZWQgdGhlICJPYmVzaXR5IiBhbmQgdGhlICJTbW9raW5nIiBjb2ZhY3Rvci4gTm90aWNlIHRoYXQgZXZlbiBpZiB0aGUgbWV0aG9kcyBzZWVtIGNvbXBsZXRlbHkgc3BlY3VsYXIsIGl0J3Mgbm90IGdyYW50ZWQgdGhhdCB0aGV5J2xsIGxlYWQgdXMgdG8gdGhlIHNhbWUgb3V0Y29tZS4KIApUbyBkbyBvbmUgbGFzdCBjcm9zcy1jaGVjayB1c2luZyB0ZXN0aW5nIG1ldGhvZHMgd2UgdXNlIGEgbWl4ZWQgbWV0aG9kIHRvIGFsbG93IHZhcmlhYmxlcyB0aGF0IHdlcmUgYWRkZWQgaW4gcHJldmlvdXMgc3RlcHMgdG8gYmUgZXhjbHVkZWQgaW4gc3VjY2VlZGluZyBzdGVwcyAodGhpcyB3YXNuJ3QgYWxsb3dlZCBpbiB0aGUgc2ltcGxlIGZvcndhcmQvc3RlcC11cCBtZXRob2QpCgpUaGUgIlN0ZXAtYm90aCIgbWV0aG9kIHlpZWxkczoKYGBge3J9CmJvdGhmaXQgPC0gb2xzX3N0ZXBfYm90aF9wKG1vZGVsLCBwZW50ID0gMC4wNSwgcHJlbSA9IDAuMDUpCmJvdGhmaXQKYGBgCkJ1dCB0aGlzIGFnYWluIHlpZWxkcyB0aGUgc2FtZSByZXN1bHQgYXMgdGhlIG9uZSB3ZSBnb3Qgd2l0aCB0aGUgc3RlcCBmb3J3YXJkIG1ldGhvZC4gQXMgd2VsbCBhcyBiZWZvcmUsIHRoZSBmYWN0IHRoYXQgd2Ugb2J0YWluZWQgdGhlIHNhbWUgcmVzdWx0IHdpdGggYWxsIHRoZSB0aHJlZSBhcHByb2FjaGVzIGlzIGEgdmVyeSBsaWthYmxlLiAKVGhpcyBzZWVtcyB0byBzdWdnZXN0IGEgbW9kZWwgb2YgZm91ciB2YXJpYWJsZXMgdGhhdCBpcyBjdXR0aW5nICJTbW9raW5nIiBhbmQgIk9iZXNpdHkiLCBnaXZlbiB0aGF0IHRoZXNlIHR3byByaXNrIGZhY3RvciBhcmUgcmVtb3ZlZCBieSBhbGwgdGhyZWUgb2Ygb3VyIGdyZWVkeSBtZXRob2RzLgoKV2Ugbm93IHRyeSBhbGwgdG9nZXRoZXIgZGlmZmVyZW50IG1ldGhvZHMgYmFzZWQgb24gSW5mb3JtYXRpb24gY3JpdGVyaW9uLiBUaGVzZSB3b3JrIGluIHN1Y2ggYSB3YXkgdGhhdCB0aGV5IHBlbmFsaXplIGJpZyBtb2RlbHMgdGhhdCBvdGhlcndpc2Ugd291bGQgYmUgc2VsZWN0ZWQgYnkgbWV0aG9kcyBzdWNoIGFzIExTRSBhbmQgTUxFLiBUaGUgbWF0aCB1bmRlcm5lYXRoIHRoaXMgYXBwcm9hY2ggaXMgYWJzb2x1dGVseSBub24gdHJpdmlhbCBhbmQgZXhwbGFpbmluZyBpdCBnb2VzIGJleW9uZCB0aGUgc2NvcGUgb2YgdGhpcyByZXNlYXJjaC4gVG8gaW1wbGVtZW50IHRoaXMgd2Ugd2lsbCB1c2UgdGhlIGZ1bmN0aW9uICJiZXN0X3N1YnNldCIgVGhhdCBpcyByZXR1cm5pbmcgdGhlIGJlc3QgbW9kZWwgY29udGFpbmluZyBmcm9tIG9uZSB0byBzaXggY292YXJpYXRlcy4gV2UgdGhlcmVmb3JlIGxpbWl0IG91ciBjb21wZXJpc29uIHRvIHRoZSBjb21wYXJpc29uIGJldHdlZW4gYWxsIHRoZSBiZXN0IHN1YnNldHMgbW9kZWxzIHRoYXQgd2UgY2FuIGhhdmUuCgpgYGB7cn0KYWxsc3ViMiA8LSBvbHNfc3RlcF9iZXN0X3N1YnNldChtb2RlbCkKYWxsc3ViMgpgYGAKVGhpcyBzZWVtcyB0byBzdWdnZXN0IGEgZGlmZmVyZW50IHJlc3VsdHMuIEFsbCBvZiB0aGVzZSBjcml0ZXJpYSBhcmUgc3VnZ2VzdGluZyB0aGF0IHRoZSBiZXN0IG1vZGVsIGlzIHRoZSBvbmUgd2l0aCBhbGwgc2l4IHRoZSBleHBsYW5hdG9yeSB2YXJpYWJsZSB3aXRoIHRoZSBleGNlcHRpb24gb2YgdGhlIFNCQyBtZXRob2QsIHRoYXQgYWdhaW4gaXMgc3VnZ2VzdGluZyB0aGUgbW9kZWwgd2l0aCBmb3VyIHZhcmlhYmxlcyBhcyBiZWZvcmUuIApUaGlzIGRpc2NyZXBhbmN5IGNhbiBiZSBleHBsYWluZWQgYnkgdGhlIGZhY3QgdGhhdCwgYXQgbGVhc3QgZm9yIHRoZSBBa2Fpa2UgSW5mb3JtYXRpb24gQ3JpdGVyaWEgdGhhdCB3ZSBzdHVkaWVkIGluIGNsYXNzLCB0aGUgdW5kZXJseWluZyBjb25zdGFudCBDIGNvdWxkIGRvbWluYXRlLiBUaGlzIG1ldGhvZCBpcyBpbiBmYWN0IG1vcmUgc3VpdGFibGUgZm9yIG1vZGVscyB3aXRoIGRpZmZlcmVudCBkaW1lbnNpb25zIHxkfC4gKE5vdGljZSBhbHNvIHRoZSB0aGUgZGlmZmVyZW5jZSBpbiBBSUMgaXMgdmVyeSBsb3c6ICRcRGVsdGEgQUlDID0gMi41OSQgKQpXaXRoIHNtYWxsIG1vZGVscyBBSUMgY2FuIGVhc2lseSBwcmVmZXIgdGhlIGNvbXBsZXRlIG1vZGVsIGFzIHRoZSBnYWluIGluICJleHBsYWluZWQgdmFyaWFuY2UiIG9idGFpbmVkIGJ5IGFkZGluZyBhIHZhcmlhYmxlIGlzIG1vcmUgdGhhbiB0aGUgcGVuYWx0eSBpbnRyb2R1Y2VkIGJ5IHRoYXQgZXh0cmEgcGFyYW1ldGVyLgoKV2UgY29uY2x1ZGUgdGhpcyBzZWN0aW9uIGJ5IHNheWluZyB0aGF0IHRoZSBiZXN0IG1vZGVsIGFmdGVyIHRoaXMgYW5hbHlzaXMgaXMgdGhlIG9uZSB3aXRoIGZvdXIgZXhwbGFuYXRvcnkgdmFyaWFibGUsIG9idGFpbmVkIHdpdGggdGhlIHRocmVlIHN0ZXAtd2lzZSBtZXRob2QKCiMgTGltaXRhdGlvbnMgb2YgdGhlIHN0dWR5IGFuZCBDb25jbHVzaW9ucwpCYXNlZCBvbiB0aGUgcmVzdWx0cyBvZiBvdXIgc3R1ZHksIHdlIGNhbiBjb25jbHVkZSB0aGF0IG91ciBsYXN0IG1vZGVsIGV4cGxhaW5zIHF1aXRlIHdlbGwgdGhlIHZhcmlhbmNlIGluIHRoZSBkYXRhIGFuZCB0aGF0IHdlIGNvbGxlY3RlZCBhYm91dCBjYW5jZXIgYW5kIHRoYXQgc29tZSBmYWN0b3JzIChmb3Igc3VyZSBpbmNsdWRpbmcgdGhlIG9uZXMgc2VsZWN0ZWQgYnkgdXMpIGFyZSBtb3JlIGluZmx1ZW50aWFsIHRoYW4gb3RoZXJzIGluIGV4cGxhaW5pbmcgdGhlIHNoYXJlIG9mIHBlb3BsZSBzdWZmZXJpbmcgb2YgY2FuY2VyIGluIGEgZ2l2ZW4gY291bnRyeS4KUmVsYXRpdmVseSBvbGRlciBhbmQgcmljaGVyIGNvdW50cmllcyAodGhlIHR3byB0aGluZ3Mgb2Z0ZW4gb3ZlcmxhcCkgcHJlc2VudCBtYW55IG1vcmUgY2FuY2VyIGNhc2VzIGluIHBlcmNlbnRhZ2UgdGhhbiB0aGUgb3RoZXJzIGFuZCB0aGUgc2FtZSB3ZSBjYW4gY29uY2x1ZGUgb2YgY291bnRyaWVzIHdpdGggYSBjb25zdW1wdGlvbiBvZiBhbGNvaG9sIGFuZCBjaWdhcmV0dGVzIGFib3ZlIHRoZSBtZWFuLiBIb3dldmVyLCBvdXIgc3R1ZHkgaGFzIGEgbG90IG9mIGxpbWl0YXRpb25zIHRoYXQgd2UgaGF2ZSB0byBpbmRpY2F0ZS4gCi0gRmlyc3QsIGFzIHdlIGhhZCB0byBjb25zdHJ1Y3QgdGhlIGRhdGEgc2V0IGJ5IG91ciBvd24sIHdlIGVuY291bnRlcmVkIHNvbWUgZGlmZmljdWx0aWVzOiB3ZSBqb2luZWQgc29tZSBkYXRhIHRvZ2V0aGVyIGludG8gYSB0YWJsZSwgYnV0IG9idmlvdXNseSB3ZSBoYWQgc29tZSBtaXNzaW5nIGRhdGEuIEl0J3Mgbm90IGVhc3kgZXZlbiBqdXN0IHRvIGNvbGxlY3QgdGhlIGRhdGEgaW4gdGhlIHNhbWUgd2F5IGZvciBhbGwgdGhlIGNvdW50cmllcyBmb3IgbW9yZSB0aGFuIDI1IHllYXIgZm9yIGFsbCB0aG9zZSBmYWN0b3JzISAKLSBTZWNvbmRseSwgd2UgaGF2ZSB0byBjb25zaWRlciB0aGUgZGlmZmVyZW5jZSBpbiBkYXRhIGF2YWlsYWJpbGl0eSB0aGF0IGlzIHByZXNlbnQgYW1vbmcgdGhlIGNvdW50cmllcy4gVG8gZ2l2ZSBhbiBleGFtcGxlOiBpdCdzIG11Y2ggZWFzaWVyIHRvIGZpbmQgYSBkYXRhIHNldCBhYm91dCBhIGdpdmVuIHRvcGljIHJlZ2FyZGluZyB0aGUgVVNBIHdpdGggcmVzcGVjdCB0byBvbmUgcmVnYXJkaW5nIEJ1cmtpbmEgRmFzby4KQmVzaWRlcyB0aGF0LCB3ZSBoYXZlIHRha2VuIGludG8gY29uc2lkZXJhdGlvbnMganVzdCBzaXggZmFjdG9ycyB0byB0cnkgdG8gZXhwbGFpbiBjYW5jZXIgaW5jaWRlbmNlLCBidXQgYXMgd2Uga25vdyBpdCBpcyBhIG11Y2ggbW9yZSBkaWZmaWN1bHQgcmVzZWFyY2ggcXVlc3Rpb246IGdlbmV0aWNhbCBoZXJpdGFnZSwgb3RoZXIgZmFjdG9ycyBvZiBjb25jZXJuaW5nIGxpZmVzdHlsZSwgb3RoZXIgZW52aXJvbm1lbnRhbCBlbGVtZW50cywgYWNjZXNzIHRvIHRoZSBoZWFsdGhjYXJlIHN5c3RlbSwgcHJldmVudGlvbiBhbmQgdHJlYXRtZW50IG9mZmVyZWQgYnkgdGhlIGNvdW50cnkgYW5kIG1hbnkgbW9yZSB0aGluZ3MgcGxheSBhIHJvbGUgaW4gZGV2ZWxvcGluZyBhIGNhbmNlciBvciBub3QuIAotIE1vcmVvdmVyLCBpdCBpcyBub3QgYW4gJ2ltbWVkaWF0ZScgZGlzZWFzZTogZmFjdG9ycyBvZiByaXNrIHN1bSB1cCBvdmVyIHRoZSB5ZWFycyBhbmQgc28gZG8gcHJvZ3Jlc3MgaW4gbWVkaWNpbmUuIFRoaXMgZW5kcyB1cCBpbiBhIGNvbXBsaWNhdGVkIGFuZCBpbnRyaWNhdGUgc2l0dWF0aW9uIHRvIGFuYWx5emUuIApEaXZpbmcgaW50byBzb21lIGRldGFpbHMsIHdlIGFsc28gaGFkIGEgcXVpdGUgc3VycHJpc2luZyByZXN1bHQ6IHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGNhbmNlciBjYXNlcyBhbmQgYWlyIHBvbGx1dGlvbiBzZWVtcyBzdHJvbmdseSBuZWdhdGl2ZSwgYXMgdGhlIHBsb3QgYXQgdGhlIGJlZ2lubmluZyBzaG93cy4gSXQgaXMgZGlmZmljdWx0IHRvIGV4cGxhaW4gc3VjaCBhIHJlc3VsdCwgYnV0IGl0IG1heSBiZSB0aGF0IHNpbmNlIHRoZSB3b3JzdCBxdWFsaXR5IG9mIGFpciBpcyBvbiBhdmVyYWdlIGluIGxlc3MgZGV2ZWxvcGVkIGNvdW50cmllcyhlZy4gTmlnZXJpYSwgUGFraXN0YW4sIEluZGlhLi4uKSwgaXQgbWF5IGJlIHRoYXQgb3RoZXIgZmFjdG9ycyBhcyB0aGUgZGVtb2dyYXBoaWMgZGlzdHJpYnV0aW9uIG9mIHRoZSBwb3B1bGF0aW9uIG9yIEdEUCwgdGhhdCB0eXBpY2FsbHkgb2J0YWluIGxvdyB2YWx1ZXMgaW4gdGhvc2UgY291bnRyaWVzICwgaGF2ZSBhIHN0cm9uZ2VyIGluZmx1ZW5jZSBvbiB0aGUgYWN0dWFsIG51bWJlciBvZiBjYW5jZXIgY2FzZXMsIGVuZGluZyBpbiB0aGlzIGNvdW50ZXItaW50dWl0aXZlIHJlc3VsdC4KVGhlIGRpdmlzaW9uIHRoYXQgd2UgbWFkZSBhdCB0aGUgYmVnaW5uaW5nIHNlZW1zIHRvIHN1Z2dlc3QgdGhhdCB0aGUgIm5vbi1yaXNrIGZhY3RvcnMiIGFyZSB0aGUgb25lIGJldHRlciBzdWl0ZWQgdG8gZGVzY3JpYmUgdGhlIGRpc3RyaWJ1dGlvbiBvZiBjYXNlcyB3b3JsZHdpZGUsIGJ1dCBhZ2FpbiB0aGF0J3Mgd2hhdCB3ZSB3YW50ZWQgZm9yIHRoaXMgcmVzZWFyY2g6IGEgbWVyZWx5IGRlc2NyaXB0aXZlIGFwcHJvYWNoLiAKV2UgY29uY2x1ZGUgYnkgc2F5aW5nIHRoYXQgYW5vdGhlciBpbnRlcmVzdGluZyBpbXByb3ZlbWVudCB0byB0aGlzIHJlc2VhcmNoIGNvdWxkIGJlIHRvIHRyeWluZyB0byByZXBlYXQgdGhlIHNhbWUgYW5hbHlzaXMgYnV0IGp1c3QgZm9jdXNpbmcgb24gZXZlcnlkYXkgaGFiaXRzIGFuZCBtYXliZSBieSBpbmNsdWRpbmcgdGhlIGludGVyYWN0aW9uIGVmZmVjdHMgd2l0aGluIHRoZSBwb3NzaWJsZSBjb3ZhcmlhdGVzIHRoYXQgd2Ugd2lsbCBjaG9vc2UgaW4gb3JkZXIgdG8gcHJvdmlkZSB0aXBzIGZvciBhbiBoZWFsdGhpZXIgcm91dGluZS4KCgojIyMgKi0+SG9wZSBtYW55IG9mIHlvdSBnb3QgdGhlIFN0YXRRdWVzdCB0cmlidXRlPC0qCgojIFNJVE9HUkFQSFkgQU5EIFJFRkVSRU5DRVMKClRoZSBzb3VyY2VzIHVzZWQgZm9yIHRoZSBkYXRhcyBhcmU6CgotIENhbmNlciAtPiBbR2xvYmFsIEJ1cmRlbiBvZiBEaXNlYXNlIENvbGxhYm9yYXRpdmUgTmV0d29yay4gR2xvYmFsIEJ1cmRlbiBvZiBEaXNlYXNlIFN0dWR5IDIwMTcgKEdCRCAyMDE3KSBSZXN1bHRzLiBTZWF0dGxlLCBVbml0ZWQgU3RhdGVzOiBJbnN0aXR1dGUgZm9yIEhlYWx0aCBNZXRyaWNzIGFuZCBFdmFsdWF0aW9uIChJSE1FKSwgMjAxOF0oaHR0cDovL2doZHguaGVhbHRoZGF0YS5vcmcvZ2JkLXJlc3VsdHMtdG9vbCkKCi0gQWlyX3BvbGx1dGlvbiAtPiBbV29ybGQgRGV2ZWxvcG1lbnQgSW5kaWNhdG9ycyAtIFdvcmxkIEJhbmsgXShodHRwOi8vZGF0YS53b3JsZGJhbmsub3JnL2RhdGEtY2F0YWxvZy93b3JsZC1kZXZlbG9wbWVudC1pbmRpY2F0b3JzKQoKLSBBbGNvb2wgLT4gW0Zvb2QgYW5kIEFncmljdWx0dXJlIE9yZ2FuaXphdGlvbiBvZiB0aGUgVW5pdGVkIE5hdGlvbnMgKEZBTykKKDIwMTcpXShodHRwOi8vd3d3LmZhby5vcmcvZmFvc3RhdC9lbi8/I2RhdGEvKQoKLSBHRFBfcGVyX2NhcHRhIC0+IFtXb3JsZCBEZXZlbG9wbWVudCBJbmRpY2F0b3JzIC0gV29ybGQgQmFuayBdKGh0dHA6Ly9kYXRhLndvcmxkYmFuay5vcmcvZGF0YS1jYXRhbG9nL3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMpCgotIE9iZXNpdHkgLT4gW1dvcmxkIEhlYWx0aCBPcmdhbml6YXRpb24gKFdITyldKGh0dHA6Ly9hcHBzLndoby5pbnQvZ2hvL2RhdGEvdmlldy5tYWluLlJFR0lPTjI0ODBBP2xhbmc9ZW4pCgotIE9sZF9hZ2VfZGVwZW5kZW5jeSAtPiBbV29ybGQgRGV2ZWxvcG1lbnQgSW5kaWNhdG9ycyAtIFdvcmxkIEJhbmtdKGh0dHA6Ly9kYXRhLndvcmxkYmFuay5vcmcvZGF0YS1jYXRhbG9nL3dvcmxkLWRldmVsb3BtZW50LWluZGljYXRvcnMpCgotIFNtb2tpbmcgLT4gW05hdGlvbmFsbHkgcmVwcmVzZW50YXRpdmUgc291cmNlcywgc3VydmV5IGRhdGFdKGh0dHA6Ly9naGR4LmhlYWx0aGRhdGEub3JnL3JlY29yZC9nbG9iYWwtc21va2luZy1wcmV2YWxlbmNlLWFuZC1jaWdhcmV0dGUtY29uc3VtcHRpb24tMTk4MC0yMDEyKQo=